hotarunx's diary

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

競プロ環境をまた作り直した

このリポジトリの通り、競プロ環境を作り直した。 こだわりポイントを書く。

github.com

外部ライブラリのインクルード

提出、ビルドで ac-library、うしライブラリ、自作ライブラリをスムーズに使えるようにしている。

ライブラリをクローンする。 うしライブラリはフォルダの中に入れている。 #include "ushi/template/template.hpp" のようにパスの先頭に ushi とつけるため。

git clone git@github.com:atcoder/ac-library.git ~/ac-library
git clone git@github.com:ei1333/library.git ~/ushi-library/ushi
git clone https://github.com/hotarunx/matikane-library.git ~/matikane-library/matikane

C++の Intellisense 設定のインクルードパスにライブラリを追記。

.vscode/c_cpp_properties.json

            "includePath": [
                "${workspaceFolder}/**",
                "~/ac-library",
                "~/ushi-library",
                "~/matikane-library"
            ],

ビルドのインクルードパスにライブラリを追記。

.vscode/tasks.json

      "type": "shell",
      "label": "C++: build active file",
      "command": "/usr/bin/g++",
      "args": [
        "${file}",
        "-o",
        "${fileDirname}/${fileBasenameNoExtension}.out",
        "-g",
        "-fsanitize=undefined",
        "-D_GLIBCXX_DEBUG",
        "-Wall",
        "-Wextra",
        "-std=gnu++17",
        "-I",
        "~/ac-library",
        "-I",
        "~/ushi-library",
        "-I",
        "~/matikane-library"
      ],

ライブラリを oj-bundle で結合して提出する。 oj-bundle のインクルードパスにもライブラリを追記。 ac-library は付属の expander.py でも結合できるが、oj-bundle で結合している。 他のライブラリと結合方法を統一するため。

.vscode/tasks.json

    {
      "label": "oj-bundle: bundle",
      "type": "shell",
      "command": "oj-bundle",
      "args": [
        "${file}",
        "-I",
        "~/ac-library",
        "-I",
        "~/ushi-library",
        "-I",
        "~/matikane-library",
        "|",
        "sed",
        "-e",
        "\"/#line.*/d\"",
        ">",
        "${fileDirname}/bundled.cpp"
      ],
      "group": "test"
    },

oj-bundleで作成される#lineの削除

oj-bundle すると、#line 1 "main.cpp" のような行が追加される。 sed で消している。

.vscode/tasks.json

    {
      "label": "oj-bundle: bundle",
      "type": "shell",
      "command": "oj-bundle",
      "args": [
        "${file}",
        "-I",
        "~/ac-library",
        "-I",
        "~/ushi-library",
        "-I",
        "~/matikane-library",
        "|",
        "sed",
        "-e",
        "\"/#line.*/d\"",
        ">",
        "${fileDirname}/bundled.cpp"
      ],
      "group": "test"
    },

https://twitter.com/d7511168/status/1518033921090670592

oj-jordan で問題をブラウザとVSCodeで開くタスク

自作の oj-prepare のラッパーソフト、oj-jordan を使っている。問題のページをブラウザで開き、テンプレートファイルを VSCode で開き、標準入力リダイレクト用のファイルを作成できる。

.vscode/tasks.json

    {
      "label": "oj-jordan: prepare",
      "type": "shell",
      "command": "oj-jordan",
      "args": ["prepare", "${input:URL}", "--stdin-file", "test/in"],
      "group": "test"
    },

テスト、提出のタスク

oj のテスト、提出のタスクがある。 提出タスクは oj-bundle タスクを依存タスクに指定している。

.vscode/tasks.json

    {
      "label": "C++: test active file",
      "type": "shell",
      "command": "oj",
      "args": [
        "test",
        "-c",
        "${fileDirname}/${fileBasenameNoExtension}.out",
        "-e",
        "1e-6"
      ],
      "dependsOn": ["C++: build active file"],
      "group": {
        "kind": "test",
        "isDefault": true
      },
      "presentation": {
        "focus": true
      },
      "options": {
        "cwd": "${fileDirname}"
      }
    },
    {
      "label": "oj: submit",
      "type": "shell",
      "command": "oj",
      "args": ["submit", "${fileDirname}/bundled.cpp"],
      "presentation": {
        "focus": true
      },
      "options": {
        "cwd": "${fileDirname}"
      },
      "dependsOn": "oj-bundle: bundle"
    },

このタスクはショートカットが割り振られており、簡単に呼び出せる。

keybindings.json

  {
    "key": "alt+t",
    "command": "workbench.action.tasks.test"
  },
  {
    "key": "alt+s",
    "command": "workbench.action.tasks.runTask",
    "args": "oj: submit",
    "when": "editorLangId != 'markdown'"
  },

ビルドの引数

警告系、デバッグ系のフラグを ON している。 ライブラリもインクルード。

.vscode/tasks.json

      "command": "/usr/bin/g++",
      "args": [
        "${file}",
        "-o",
        "${fileDirname}/${fileBasenameNoExtension}.out",
        "-g",
        "-fsanitize=undefined",
        "-D_GLIBCXX_DEBUG",
        "-Wall",
        "-Wextra",
        "-std=gnu++17",
        "-I",
        "~/ac-library",
        "-I",
        "~/ushi-library",
        "-I",
        "~/matikane-library"
      ],

デバッグ用の標準入力用ファイルの作成

oj-jordan で標準入力用の空ファイルを作成している。 デバッグ時に標準入力をリダイレクトしている。

    {
      "name": "C++: debug active file",
      "type": "cppdbg",
      "request": "launch",
      "program": "${fileDirname}/${fileBasenameNoExtension}.out",
      "args": ["<", "${fileDirname}/test/in"],
      "stopAtEntry": false,
      "cwd": "${workspaceFolder}",
      "MIMode": "gdb",
      "setupCommands": [
        {
          "description": "gdb の再フォーマットを有効にする",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ],
      "preLaunchTask": "C++: build active file",
      "miDebuggerPath": "gdb"
    },

oj-template のテンプレート作成

自作ファイルのテンプレートをインクルードするように、oj-template のテンプレートを微変更。

other/template/main.cpp

    if platform.system() == "Linux" and "clang" not in os.environ.get("CXX", "g++"):
        include = "#include \"matikane/template/template.hpp\""
    else:

CppCheck

静的解析ツール CppCheck を使っている。

フォーマット設定

Google をベースにインデント幅、行長を自分好みに変更。

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