自分好みの環境構築で全部まとまってる記事は自分で作るしかない。
target
- (OS: Windows)
- MSYS2 MinGW64 GCC
- Git
- Visual Studio Code
- atcoder-tools
install MSYS2
(参考)
MSYS2の導入 - 東京大学工学部 精密工学科 プログラミング応用 I・II
Windows10の開発環境をMSYS2で再構築 - Qiita
MSYS2 による gcc 開発環境の構築 - Qiita
インストール先のフォルダを
C:\programming\msys64
に変更する。諸々のツールを追加する際に C ドライブ直下が散逸するのを防ぎたい。
起動する MSYS2 は MinGW 64bit 版で統一する。
run pacman
パッケージ管理ツールの更新には色々流儀がありそう。
$ pacman -Sy pacman $ pacman --needed -S bash pacman pacman-mirrors msys2-runtime $ pacman -Su $ pacman -S base-devel mingw-w64-x86_64-toolchain
各コマンドごとにターミナルを再起動して、更新されなくなるまで再度同じコマンドを実行させると安心できそう。
最後の mingw-w64-x86_64-toolchain
をインストールすると GCC とともに Python もインストールされるはず。Group: mingw-w64-x86_64-toolchain - MSYS2 Packages から
toolchain > pkgconf > meson > python
の順に遡って辿れるので多分そう。
add PATH
Windows -> MSYS2
- ユーザー環境変数のPathに
C:\programming\msys64\mingw64\bin
を追加
MSYS2 -> Windows
- ユーザー環境変数に変数
MSYS2_PATH_TYPE
、値inherit
を追加 - MSYS2でPATH が引き継がれない件 | こぼれネット
install Git
(参考)
【超入門】初心者のためのGitとGitHubの使い方 - RAKUS Developers Blog | ラクス エンジニアブログ
VSCodeでGit・GitHubを使う方法を解説する【初心者向き】
リポジトリをクローンする - GitHub Docs
GitHub のプライベートリポジトリ上で競プロ用のアルゴリズムテンプレートを管理する。リポジトリ名は competitive
にしてある。ついでに .vscode
フォルダも push しておくと楽ができる。
改行コードの部分だけ気を付けてインストールする。デフォルトエディターの設定はそのままで問題ない。
git config
$ git config --global user.name [[ any_user_name ]] $ git config --global user.email [[ any_email_address ]]
git clone
Git Bash を起動する。
$ cd /c/programming $ git clone https://github.com/[[ user_name ]]/competitive.git
C:\programming\competitive
フォルダが作成されていることを確認する。
GitHub 上に当該リポジトリをまだ作成していない場合は、
$ cd /c/programming $ mkdir competitive $ cd competitive $ git init
でローカルリポジトリを作成する。
install Visual Studio Code
(参考)
VSCodeのインストール方法について解説する【初心者向き】
インストール先は変えずにそのままインストールする。PATH は自動的に追加される。
extensions
- Japanese Language Pack for Visual Studio Code
- C/C++
- Bracket Lens
open folder
Visual Studio Code の [フォルダを開く] から
C:\programming\competitive
を開く。
git clone
していない場合は .vscode
フォルダ内の json ファイルを書き換えていく。それぞれファイルが存在しない場合は新規で作成すること。
.json files here (4 contents)
書き換えるべき部分だけ抜き出して記述してある。MSYS2 のインストール先が異なる場合はパスを適宜読み替えてほしい。
// c_cpp_properties.json { "configurations": [ { "name": "Win32", "includePath": [ "${workspaceFolder}/**", "C:\\programming\\msys64\\mingw64\\include" ], "compilerPath": "C:\\programming\\msys64\\mingw64\\bin\\gcc.exe", "intelliSenseMode": "gcc-x64", "cppStandard": "c++20" } ], "version": 4 }
// settings.json { "C_Cpp.default.includePath": [ "C:\\programming\\msys64\\mingw64\\include", ], "C_Cpp.default.compilerPath": "C:\\programming\\msys64\\mingw64\\bin\\g++.exe", "C_Cpp.default.cppStandard": "c++20", "C_Cpp.default.intelliSenseMode": "gcc-x64" }
g++ でデバッグすることも考慮して以下の 2 つも一応書き換えておく。ショートカットキーはあとで上書きするので、少なくとも AtCoder をやる上では意図せずデバッグが開始されることはない。
// tasks.json { "version": "2.0.0", "tasks": [ { "label": "g++.exe build active file", "type": "process", "command": "C:\\programming\\msys64\\mingw64\\bin\\g++.exe", "args": [ "-std=c++20", "-g", "-O2", "${file}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe", "-lgdi32" ], "group": { "kind": "build", "isDefault": false } } ] }
"isDefault": true
のままだと atcoder-tools でビルドしたときに "args"
が上記の内容に置き換わってしまうので注意する。
// launch.json { "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${fileDirname}\\${fileBasenameNoExtension}.exe", "args": [], "environment": [], "cwd": "${workspaceFolder}", "stopAtEntry": false, "externalConsole": true, "MIMode": "gdb", "miDebuggerPath": "C:\\programming\\msys64\\mingw64\\bin\\gdb.exe", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ], "preLaunchTask": "g++.exe build active file" } ] }
customize
左下の歯車アイコン、あるいは Ctrl+,
から [設定] を開き、右上のアイコンから [設定 (JSON) を開く] を探し出して settings.json
を開く。好みに合わせてカスタマイズする。
// settings.json { "workbench.startupEditor": "none", "editor.tabSize": 2, "files.eol": "\n" }
install atcoder-tools
(参考)
Visual Studio Code の統合ターミナルで MSYS2 の bash を選択できるようにする - Qiita
MSYS2 で pip を使う - Qiita
VSCodeでAtCoder用環境を構築する|デロイト トーマツ ウェブサービス株式会社(DWS)公式ブログ
便利! AtCoder で競技プログラミングをするときに重宝する AtCoder Tools のご紹介 - Qiita
GitHub - kyuridenamida/atcoder-tools: Convenient modules & tools for AtCoder users, written in Python 3.6
ここからが結構長い。
before installing...
set MSYS2 as default terminal
Visual Studio Code の規定のターミナルを MSYS2 に変更する。カスタマイズ時に使用した settings.json
に追記する。"PowerShell" "Command Prompt" "Git Bash" の項目は変更しなくて良い。もしこれらの項目が存在していないなら、Ctrl+,
で設定を開き terminal.integrated.profiles.windows
で検索して [settings.json で編集] を押せば自動入力されるはず。
// settings.json { "terminal.integrated.profiles.windows": { "PowerShell": { "source": "PowerShell", "icon": "terminal-powershell" }, "Command Prompt": { "path": [ "${env:windir}\\Sysnative\\cmd.exe", "${env:windir}\\System32\\cmd.exe" ], "args": [], "icon": "terminal-cmd" }, "Git Bash": { "source": "Git Bash" }, "MSYS2 Bash": { "path": [ "C:\\programming\\msys64\\usr\\bin\\bash.exe" ], "args": [ "--login" ], "env": { "MSYSTEM": "MINGW64", "CHERE_INVOKING": "1" }, "overrideName": true } }, "terminal.integrated.defaultProfile.windows": "MSYS2 Bash" }
install pip
MSYS2 MINGW64 を起動する。MSYS2 で pip コマンドを使用できるようにする。Visual Studio Code のターミナルでも作業可能だが、その際は
$ cd ~
でホームディレクトリに移動しておく必要があるかも[要検証]。
$ pacman -S python3-pip $ pip3 install --upgrade pip
installing now...
そのまま MSYS2 上で作業を進める。
$ pip3 install atcoder-tools $ pip3 install markupsafe==2.0.1
after installing...
~/.atcodertools.toml
を作成する。ホームディレクトリは /c/programming/msys64/home/[[ user_name ]]
になっているはず。
# .atcodertools.toml [codestyle] indent_type='space' # 'tab' or 'space' indent_width=2 template_file='/c/programming/competitive/template.cpp' workspace_dir='/c/programming/competitive/atcoder-workspace/' lang='cpp' # Check README.md for the supported languages. # code_generator_toml="~/universal_code_generator.toml" [postprocess] # exec_on_each_problem_dir='' # exec_on_contest_dir='' [compiler] compile_command='g++ main.cpp -o main -std=gnu++20 -O2 -Wall -Wextra' compile_only_when_diff_detected=true [tester] compile_before_testing=true compile_only_when_diff_detected=true timeout_adjustment=1.2 [etc] download_without_login=false parallel_download=false save_no_session_cache=false skip_existing_problems=true in_example_format="in_{}.txt" out_example_format="out_{}.txt"
[postprocess]
についてはまた後で設定する。
コード生成テンプレートファイルがない場合は作成する。
template.cpp here (1 content)
// template.cpp #include <bits/stdc++.h> using namespace std; #define ALL(a) begin(a), end(a) #define RALL(a) rbegin(a), rend(a) using ll = long long; using pii = pair<int, int>; using pll = pair<ll, ll>; template<typename T> using Graph = vector<vector<T>>; template<typename T> using Spacial = vector<vector<vector<T>>>; template<typename T> using greater_priority_queue = priority_queue<T, vector<T>, greater<T>>; {% if mod %} constexpr int MOD = {{ mod }}; {% else %} constexpr int MOD = 998244353; {% endif %} const int dx[4] = { 1, 0, -1, 0 }; const int dy[4] = { 0, 1, 0, -1 }; char interval[2] = {' ', '\n'}; template<typename T, typename... Args> auto make_vector(T x, int arg, Args... args) { if constexpr(sizeof...(args) == 0) return vector<T>(arg, x); else return vector(arg, make_vector<T>(x, args...)); } template<typename T> struct is_plural : false_type{}; template<typename T1, typename T2> struct is_plural<pair<T1, T2>> : true_type{}; template<typename T> struct is_plural<vector<T>> : true_type{}; template<typename T> struct is_plural<complex<T>> : true_type{}; template<> struct is_plural<string> : true_type{}; template<typename T1, typename T2> istream& operator>>(istream& is, pair<T1, T2>& p) { return is >> p.first >> p.second; } template<typename T1, typename T2> ostream& operator<<(ostream& os, const pair<T1, T2>& p) { return os << p.first << ' ' << p.second; } template<typename T> istream& operator>>(istream& is, vector<T>& vec) { for(auto itr = vec.begin(); itr != vec.end(); ++itr) is >> *itr; return is; } template<typename T> ostream& operator<<(ostream& os, const vector<T>& vec) { if(vec.empty()) return os; bool pl = is_plural<T>(); os << vec.front(); for(auto itr = ++vec.begin(); itr != vec.end(); ++itr) os << interval[pl] << *itr; return os; } template<typename T> istream& operator>>(istream& is, complex<T>& x) { T a, b; is >> a >> b; x = complex<T>(a, b); return is; } template<typename T> ostream& operator<<(ostream& os, const complex<T>& x) { return os << x.real() << ' ' << x.imag(); } bool CoutYN(bool a, string yes = {% if yes_str %}"{{ yes_str }}"{% else %}"Yes"{% endif %}, string no = {% if no_str %}"{{ no_str }}"{% else %}"No"{% endif %}) { cout << (a ? yes : no) << '\n'; return a; } template<typename T1, typename T2> inline bool chmax(T1& a, T2 b) { return a < b && (a = b, true); } template<typename T1, typename T2> inline bool chmin(T1& a, T2 b) { return a > b && (a = b, true); } template<typename... Args> void debugger(int, const char*, const Args&...); #define debug(...) debugger(__LINE__, #__VA_ARGS__, __VA_ARGS__) /* -------- <templates end> -------- */ void solve() { } /* -------- <programs end> -------- */ #define DEBUG #ifdef DEBUG void dbg() { cerr << '\n'; } template<typename T, typename... Args> void dbg(const T& x, const Args&... args) { cerr << '\n' << x; dbg(args...); } template<typename... Args> void debugger(int line, const char* str, const Args&... args) { cerr << line << " [" << str << "]:"; dbg(args...); }; #else template<typename... Args> void debugger(int line, const char* str, const Args&... args) {}; #endif #define COMPLEX_COMPARE #ifdef COMPLEX_COMPARE namespace std { template<typename T> bool operator<(const complex<T>& l, const complex<T>& r) { return real(l) != real(r) ? real(l) < real(r) : imag(l) < imag(r); } } #endif signed main() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(10); solve(); return 0; }
これで一旦、ターミナル経由ならば atcoder-tools のコマンドが不自由なく使用できるようになっている。
set up keyboard shortcuts
(参考)
コマンドライン | 非公式 - Visual Studio Code Docs
Visual Studio Codeでタスク機能を使ってみよう - とことんDevOps | 日本仮想化技術のDevOps技術情報メディア
【VSCode】キーボードショートカットを編集してみる
キーボードショートカットだけで機能させることを最終目標としている。
behavior of atcoder-tools gen
通常はファイルを生成して終わりだが、折角なので生成ファイルを全て開きたい。
よほどのことがない限り前から問題を解いていくので、後ろから生成ファイルを開いていく。AC してファイルを閉じていくと幸せになれそう。
set postprocess in .atcodertools.toml
一旦放置していた .atcodertools.toml
を修正する。
# .atcodertools.toml [postprocess] exec_on_each_problem_dir='basename `pwd` >> ../.atcodertools_directories.txt' exec_on_contest_dir='data=(`tac .atcodertools_directories.txt`); if [ ${#data[@]} -le 10 ]; then for dir in ${data[@]}; do code -g ${dir}/main.cpp:45:2; done; fi'
ファイル生成ごとにディレクトリ名を *\atcoder-workspace\[[ contest_id ]]\.atcodertools_directories.txt
に追記し、すべてのファイル生成が終了したら追記内容を逆順に読み込み、読み込んだディレクトリ名順に *\atcoder-workspace\[[ contest_id ]]\[[ dirname ]]\main.cpp
の 45 行 2 列目にキャレットを置いて開く、という挙動になっている。もし問題数が 10 問を超えていたらファイルを開かないようにしてある。
それなりに重たい処理になるので、マシンパワーが足りなければコメントアウトすることを推奨する。
set atcoder-tools commands in tasks.json
C:\programming\competitive\.vscode\tasks.json
に追記する。もちろん、既に GitHub 上で管理できているなら不要な作業である。
tasks.json here (1 content)
// tasks.json { "tasks": [ { "label": "atcoder-tools gen", "type": "shell", "command": "atcoder-tools gen ${input:contest_id}", "presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared", "showReuseMessage": true, "clear": false, "close": true }, "options": { "cwd": "${workspaceRoot}" } }, { "label": "atcoder-tools test", "type": "shell", "command": "atcoder-tools test", "presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared", "showReuseMessage": true, "clear": false, "close": false }, "options": { "cwd": "${fileDirname}" } }, { "label": "atcoder-tools submit", "type": "shell", "command": "atcoder-tools submit -u", "presentation": { "echo": true, "reveal": "always", "focus": true, "panel": "shared", "showReuseMessage": true, "clear": false, "close": false }, "options": { "cwd": "${fileDirname}" } } ], "inputs": [ { "id": "contest_id", "type": "promptString", "description": "enter the AtCoder contest_id", "default": "" } ] }
特に "tasks": "focus"
や "tasks": "close"
については好みに合わせて書き換えるべし。
"cwd"
の設定はキーバインドと連携させるので記述通りにすること。
set keyboard shortcuts in keybindings.json
左下の歯車アイコン、あるいは Ctrl+K Ctrl+S
から [キーボード ショートカット] を開き、右上のアイコンから [キーボード ショートカットを開く (JSON)] を探し出して keybindings.json
を開く。
// keybindings.json [ { "key": "Ctrl+F1", "command": "workbench.action.tasks.runTask", "when": "resourceDirname == /c/programming/competitive", "args": "atcoder-tools gen" }, { "key": "F5", "command": "workbench.action.tasks.runTask", "when": "editorTextFocus && resourcePath =~ /^.*atcoder-workspace.*main.cpp$/", "args": "atcoder-tools test" }, { "key": "F9", "command": "workbench.action.tasks.runTask", "when": "editorTextFocus && resourcePath =~ /^.*atcoder-workspace.*main.cpp$/", "args": "atcoder-tools submit" } ]
Visual Studio Code のエクスプローラー上で C:\programming\competitive
が開いているなら問題なく動作するはず。
F5 に atcoder-tools test
を割り当てることで [デバッグの開始] を抑制している。別のキーを割り当てる際は [キーボード ショートカット] から検索をかけてみて、意図しない挙動が起こらないように注意する。
git push (optional)
(参考)
【超入門】初心者のためのGitとGitHubの使い方 - RAKUS Developers Blog | ラクス エンジニアブログ (再掲)
VSCodeでGit・GitHubを使う方法を解説する【初心者向き】 (再掲)
簡潔に記す。わからなければ上記サイトを参照すること。
.gitignore
C:\programming\competitive\.gitignore
を作成する。
.gitignore here (1 content)
# .gitignore # git ls-files --others --exclude-standard # Ignore files generated by atcoder-tools /atcoder-workspace/ # Ignore any other files if needed
push
Visual Studio Code の左上のアイコン群から [ソース管理] を開き、ステージングしてから [コミットしてプッシュ] する。
winning run...
後書きのようなもの。
PC を新調したので、競プロ歴 5 年目にしてようやく自動化ツールを導入した。
当初は online-judge-tools を導入する予定だったが、WSL 環境を嫌って MSYS2 でどうにかならないか丸 1 日かけて、結局どうにもならず。エラーが発生する度に原因を探し出して解決し、そして新たなエラーが発生する、というループを何度か繰り返しているうちにエラーを解決できなくなって諦めた。
atcoder-tools の方でも、インストール自体は難なくできたものの細かな仕様が不明瞭で(それはそう)、ソースコードを辿ったりシェルコマンドの構文を調べたり実験してみたり、そうこうしているうちに更に 2 日かかってしまった。その分個人的にはかなり満足のいく環境になったので良しとする。
あとはアルゴリズムテンプレートの自動挿入ができれば完璧か。
[2023/09/20 追記] 自動挿入できるようになった。