hotaruの蛍雪日記

競プロとゲームをしています

競技プログラミング用にVSCodeのtasksとlaunchを書く

f:id:hotarunx:20201112021616g:plain

online-judge-toolsを導入した。 テストや提出のタスクを作る。 設定ファイルを書いた。

c_cpp_properties.json

IntelliSenseの構成らしい。 C++17にして警告オプションをつけた。

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/g++",
            "cStandard": "gnu17",
            "cppStandard": "gnu++17",
            "intelliSenseMode": "gcc-x64",
            "compilerArgs": [
                "-g",
                "-Wall",
                "-Wextra",
                "-Werror"
            ]
        }
    ],
    "version": 4
}

tasks.json

VSCode標準のタスク機能の設定ファイル。 タスク、特にビルドタスクを設定できる。

コンパイル・テスト・提出するタスクを作成した。 dependsOnを使うことで、ある依存タスク(タスクを実行する前に実行するタスク)を設定できる。 次のタスクを作成した。

  • build: 開いているファイルをオプション付きでコンパイルする。実行ファイルはカレントディレクトリに作成する。
  • test active file: 開いているファイルをコンパイルしてojでテストする。
  • submit: テストに通ったら提出する。
  • expand acl: ac-libraryのexpander.pyで展開する。
  • submit with acl: テストに通ったらexpander.pyで展開して提出する。

実行ファイルは./a.outということにした。 本当は実行ファイルはソースと同じ場所にあるようにしたかったが、${fileDirName}が想定通りの値ではなかったり、タスクのカレントディレクトリがよくわからないのでやめた。

submitタスクを実行すると、開いているファイルを./submit.cppにコピーして(ac-libraryを展開して)提出する。 ojは提出するファイルがカレントディレクトリにあったほうが都合がいいようなのでこうした。

  1. -Wunused-variableなどの警告をされるようなコードにエディタ上で下波線を引いて警告してほしい。
  2. もしくはコンパイル時に警告を見たい。
  3. どちらもできなかった。
  4. タスクが正常終了すると標準エラー出力はコンソールに表示されない。
  5. タスクが異常終了すると標準エラー出力はコンソールに表示される。
  6. なので警告ありエラー無しのコードをビルドタスクしても警告が見れない。
  7. この問題を解決するために警告があればエラー扱いする-Werrorを追加した。
  8. なにか良い解決方法があれば教えて下さい。
{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "cppbuild",
            "label": "build",
            "command": "/usr/bin/g++",
            "args": [
                "${file}",
                "-o",
                "${workspaceFolder}/a.out",
                "-g",
                "-Wall",
                "-Wextra",
                "-Werror",
                "-std=gnu++17",
                "-I",
                "${workspaceFolder}/ac-library"
            ],
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "compiler: /usr/bin/g++",
            "presentation": {
                "focus": true
            }
        },
        {
            "label": "test active file",
            "type": "shell",
            "command": "oj",
            "args": [
                "test",
            ],
            "dependsOn": [
                "build"
            ],
            "problemMatcher": [],
            "group": {
                "kind": "test",
                "isDefault": true
            }
        },
        {
            "label": "auto make input.txt",
            "type": "shell",
            "command": "touch input.txt",
            "runOptions": {
                "runOn": "folderOpen"
            }
        },
        {
            "label": "copy",
            "type": "shell",
            "command": "cp",
            "args": [
                "${file}",
                "submit.cpp"
            ],
        },
        {
            "label": "submit",
            "type": "shell",
            "command": "oj",
            "args": [
                "s",
                "submit.cpp",
                "-y"
            ],
            "dependsOn": [
                "copy",
                "test"
            ],
            "problemMatcher": [],
            "detail": "現在開いているファイルを提出する"
        },
        {
            "label": "submit with acl",
            "type": "shell",
            "command": "oj",
            "args": [
                "s",
                "submit.cpp",
                "-y"
            ],
            "dependsOn": [
                "test",
                "copy expanded file"
            ],
            "problemMatcher": [],
            "detail": "現在開いているファイルをACLを展開して提出する。"
        },
        {
            "label": "expand acl",
            "type": "shell",
            "command": "python3",
            "args": [
                "expander.py",
                "../submit.cpp"
            ],
            "options": {
                "cwd": "${workspaceFolder}/ac-library"
            },
            "problemMatcher": [],
            "dependsOn": [
                "copy"
            ],
        },
        {
            "label": "copy expanded file",
            "command": "cp",
            "args": [
                "ac-library/combined.cpp",
                "submit.cpp"
            ],
            "dependsOn": "expand acl"
        },
    ]
}

launch.json

プログラムをデバッグ・実行する構成。 標準入力を./input.txtにリダイレクトするようにした。

{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "g++ - アクティブ ファイルのビルドとデバッグ",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceRoot}/a.out",
            "args": [
                "<",
                "input.txt"
            ],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "gdb の再フォーマットを有効にする",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build",
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}

settings.json

フォーマットスタイルはGoogleかつインデント幅4にした。

{
    "C_Cpp.clang_format_style": " { BasedOnStyle: Google, UseTab: Never, IndentWidth: 4}",
}

できるようになったこと

テスト・提出・ac-libraryの展開をタスクにまとめた。 タスクは次の方法で実行するのが良いと思います。

  1. Ctrl + Shift + P
  2. run tasksと入力
  3. タスク名を入力

やりたかったこと

  • 実行可能ファイルをソースコードと同じ場所に作る。
  • 実行可能ファイルがソースコードより修正時間が新しければビルドしない。
    • 修正時間の確認はtestコマンドの-ntオプションを使う。

つまったところ

  • ビルドタスクのargsを"-I", "ac-library"にして失敗した。
  • tasks.json, launch.jsonのパス関係がよくわからない。
  • tasks.json, launch.jsonはcppファイルを開いてデバッグしようとすると自動で作成されるようだ。