このリポジトリの通り、競プロ環境を作り直した。 こだわりポイントを書く。
- 外部ライブラリのインクルード
- oj-bundleで作成される#lineの削除
- oj-jordan で問題をブラウザとVSCodeで開くタスク
- テスト、提出のタスク
- ビルドの引数
- デバッグ用の標準入力用ファイルの作成
- oj-template のテンプレート作成
- CppCheck
- フォーマット設定
外部ライブラリのインクルード
提出、ビルドで 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}",