7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

競プロ用の環境構築覚書 C++&VSCode(&WSL2)

Last updated at Posted at 2024-05-29

はじめに

やると快適になるけれど、何かと面倒な環境構築。
私は環境構築への苦手意識が強くあったのですが、3回くらいやって少しは慣れた気がするので今のうちにメモをしておきます。
もし記事内容に明らかな誤りがあれば、コメント等でご指摘いただけると幸いです。

当記事ではC++201の導入、AtCoder Libraryの導入、<bits/stdc++.h>ヘッダのプリコンパイル、コンパイルと実行のコマンド(ShellScript)を取り扱います。
Linuxについての知識が一切ない人でも大丈夫だと思います。

なお、想定環境としてはWindows11+WSL2でVSCodeを利用する形ですが、Windows10でも概ね同様だと思います。
LinuxユーザでもWSL関連以外の内容は共通しています。MacOSはわかりかねます…

最終的にはこのようなディレクトリ2構成になります。ac-libraryディレクトリを作業ディレクトリ下に置くかはお好みで分かれると思いますが、今回の記事では外に置きます。
私の環境ではac-libraryディレクトリを作業ディレクトリ直下に置いていないと動作しないことを確認したので、作業ディレクトリ直下に置く方針に記事を修正しました。 [2024/07/01 追記]

また、main.cpp以外のcppファイルも同様に使用できます。a.cppなど。

competitive/
    ├ ac-library/
    │   ├ atcoder/
    │   └ expandar.py
    ├ .vscode/
    │   ├ c_cpp_properties.json
    │   └ settings.json
    ├ sh/
    │   ├ build.sh
    │   └ io.sh
    ├ a.out
    ├ in.txt
    ├ main.cpp
    └ out.txt

目次

  1. VSCodeの導入
  2. WSLの導入 (Windowsユーザのみ)
  3. C++の導入、バージョン設定
  4. VSCode側の設定
  5. AtCoder Libraryの導入
  6. <bits/stdc++.h>ヘッダのプリコンパイル
  7. 実行用ShellScriptの作成
  8. おわり

VSCodeの導入

VSCodeを使用するので、まずはVSCodeをインストールしておきましょう。

こちらのリンク先ページに飛び、現在使用しているOSに合わせてダウンロードボタンを押下します。想定読者となるWindowsユーザの方は「Windows」でよいです。

WSLの導入 (Windowsユーザのみ)

WSL (Windows Subsystem for Linux)を利用して、実行環境をLinux上に移します。一見回りくどいようですが、Windows上でやるよりも色々と都合がよいためです。
なお、Windows以外のユーザはこの項を飛ばして構いません。

これらの記事を参考に進めればよいと思います(特に二つ目の記事)。

具体的には、以下の手順を行えばよいです。
Windows PowerShellかコマンドプロンプトを「管理者として実行」で開いて、以下のコマンドを実行します。

wsl --install

その後PCを再起動します。Linux側のターミナル (既定ではUbuntu) を開き、こちらでLinux側のユーザー名とパスワードを設定します。

Linux側のユーザ名とパスワードはどちらも半角英数字のみを用いるほうがよいです。
入力中のパスワードは一切表示されない仕様なので、正確に入力してください。パスワードは必ず忘れないでください。

ただし、バージョンが古いWindows10を利用している人は、こちらの記事に沿って進める必要があります(バージョン等の詳細は一つ目の記事を参照のこと)。

C++の導入、バージョン設定

ここからは、コマンドの実行はすべてLinux側のターミナルで行います。既定ではUbuntuです。
image.png

こちらの記事の「C言語のコンパイラを導入する」の項に沿って進めればよいです。具体的には以下の手順でコマンドを実行します。

sudo apt update
sudo apt upgrade
sudo apt install build-essential

これでC++自体は実行できるようになりましたが、バージョン関係の設定も必要です。

こちらの記事の手順に沿って、gcc及びg++の別バージョンをインストールし、update-alternativesコマンドの設定もしておきましょう。これによりC++20環境を利用できます。
具体的には以下の手順を実行します。12の部分は適宜最新のバージョンの数値に置き換えてください(詳しくは後述)。

sudo apt install gcc-12
sudo apt install g++-12
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 12
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 12

AtCoderでは各コンテストページの下部に「ルール」と書かれたリンクが貼られており例: ARC178 - ルール、このページの「言語」の項から実行環境を確認することができます。最新の実行環境に合わせて上記の設定をしてください。
image.png

VSCode側の設定

VSCode側の設定も進めていきます。
まずはWSLをVSCodeと接続します。

WSLとの接続

以下のコマンドを実行します。実行後はLinuxのターミナルを一旦終了しておきましょう。

sudo apt-get update
sudo apt-get install wget ca-certificates

次に、VSCodeを起動して「WSL」拡張機能をインストールします。
image.png

一度VSCodeを終了します。
Linuxのターミナルを起動し、以下を実行します。

mkdir competitive
code competitive

作業ディレクトリcompetitiveを作成し、VSCodeで開きました。competitiveの部分は好きな名前でよいです。

VSCodeの左下にWSL: Ubuntuなどと表示されていたらWSLとの接続は完了です。
image.png

C++の設定

VSCode上でC++を快適に書くための設定をしていきます。
「C/C++」拡張機能をインストールします。
image.png

ほかの「C/C++ Extension Pack」などの拡張機能も自動的にインストールされているはずです。インストールしたらVSCodeを再起動してください。

Ctrl+Shift+Pでコマンドパレットを開き、「C/C++: Edit Configurations (JSON)」を押下します。
.vscodeディレクトリが作業ディレクトリ下に作成され、その中にc_cpp_properties.jsonが作成されます。

こんな感じの内容を記述していきます。

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",
                "~/competitive/ac-library"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c17",
            "cppStandard": "gnu++20",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

includePath"~/competitive/ac-library"に赤波線が引かれていると思いますが、これはちょっと無視して先に進みます。

ついでに、画面左上のFileからPreferences>Settingsへと遷移して設定できることを知っておきましょう。
設定に関しては人それぞれなので、基本的には使いながら適宜設定していけばよいです。Workspaceの設定をいじるほうが良いと思います3
なお、今回の記事の構成に合わせる場合、Files: Auto SaveonFocusChangeにしておくことを推奨します。

AtCoder Libraryの導入

AtCoder Libraryという便利なAtCoder公式ライブラリ集があります。せっかく環境構築をするからにはこれも導入しておきましょう。
AtCoder Libraryを知らないという人は以下のリンク先の記事を参考にしてください。
ドキュメント: https://atcoder.github.io/ac-library/production/document_ja/
紹介いろいろ: https://atcoder.jp/posts/517

こちらのGitHubから、画面中央-右上あたりの「Code」>「Download ZIP」を押下します。
image.png
ダウンロードしたzipファイルを展開し、Linux側に移します。
WSLであれば、Windows標準の「エクスプローラー」からLinux環境のファイルにも干渉できるので、普通にコピペなりドラッグアンドドロップなりをするとよいです。

移行先はLinux > Ubuntu > home > [ユーザ名] > ここ(ac-library)です4。以下では、これをac-libraryというディレクトリ名にしたと仮定して話を進めます。

なお、展開したフォルダ(ac-library-master)内にはそこそこのファイルが入っていたと思いますが、ac-libraryに移しておくべきなのは

atcoder expander.py

くらいだと思います。

あとはc_cpp_properties.jsonincludePathにac-libraryのパスを渡して、IntelliSenseに認識させておきます(もう上でやっています)。
includePathがこのようになっていればよいです (// の行はコメントにつき不要)。

"includePath": [
    "${workspaceFolder}/**",
    "~/competitive/ac-library"
]
// 2行目は /home/[ユーザ名]/[作業ディレクトリ名]/ac-libraryでもいい

これでAtCoder Libraryの導入は完了です。

<bits/stdc++.h>ヘッダのプリコンパイル

参考:5

記事執筆時点とは使用すべきg++等のバージョンが変わっている可能性もあります。ここで紹介する手順は適宜最新のバージョンに読み替えながら行ってください。

ヘッダファイルのプリコンパイルをしておくと、一回のコンパイル時間を短縮することができます。何回もコンパイルすることを考えると、できる限りコンパイル時間は短縮しておきたいところです。
ここでは<bits/stdc++.h>ヘッダをプリコンパイルします6

まずディレクトリを移行します。

cd /usr/include/x86_64-linux-gnu/c++/12/bits

そして普段使うコンパイルオプションに合わせて以下のコマンドを実行、プリコンパイルヘッダを生成します。

sudo g++ [オプション] stdc++.h

当記事では以下のコマンドを実行します。

sudo g++ -std=gnu++20 -O2 -Wall -Wextra stdc++.h

こうすることで.gchファイルが生成されているはずです。

ls

を実行してstdc++.gchが表示されているか確認しましょう。

これでプリコンパイルは完了です。.gch生成時と同じオプションでコンパイルした場合、プリコンパイルヘッダが使用されて速くコンパイルされます。

(<atcoder/all>もプリコンパイルできたらいいんですが、たしかプリコンパイルヘッダは一つしか使えなかった…はずです。要出典。
そうだとしても、ローカル環境ではヘッダファイルをまとめたものをプリコンパイルして使用し、外部環境では個別に展開する…とか頑張ればいけると思うんですが、難しそうなので逃げています。
さすがに毎回ACLを使うことはないと思うので、ACL関連は適宜includeする形をとっています。)

実行用ShellScriptの作成

ここまで進めた時点で、すでにC++環境は完成しています。ですが、これから毎回コンパイルをするたびに

g++ -std=gnu++20 -O2 -Wall -Wextra main.cpp

とは打ちたくない気持ちになります。ショートカットのようなものを定義して楽をします。

ShellScriptという形式の(.sh)ファイルを作成していきます。
まず.shファイルをまとめるsh/ディレクトリを作成します。(任意)

mkdir sh
cd sh

コンパイルをするためのShellScript build.shを作成します。

code build.sh

build.shに以下の内容を記述します。

#! /bin/bash
cd ~/competitive/
if [ $# != 1 ]; then
    count_atcoder=$(grep -c "atcoder" main.cpp)
    if [ ${count_atcoder} -gt 1 ]; then
        g++ -std=gnu++20 -O2 -Wall -Wextra -I./ac-library/ main.cpp
    else
        g++ -std=gnu++20 -O2 -Wall -Wextra main.cpp
    fi
    exit 0
fi

FILE=$1
count_atcoder=$(grep -c "atcoder" ${FILE}.cpp)
if [ ${count_atcoder} -gt 1 ]; then
    g++ -std=gnu++20 -O2 -Wall -Wextra -I./ac-library ${FILE}.cpp
else
    g++ -std=gnu++20 -O2 -Wall -Wextra ${FILE}.cpp
fi

随分ごちゃごちゃしていますが、

  • 任意の.cppファイルをコンパイルする
  • ソースファイル内に"atcoder"が含まれているならACLを利用するとみなして、コンパイルオプションを変更する

を実現させたためです。多分もっといい書き方はありますが…7
こんな感じで使います。

./build.sh         // main.cppをコンパイル
./build.sh a       // a.cppをコンパイル
./build.sh test    // test.cppをコンパイル

保存したら、

chmod +x ./build.sh

で実行権限を与えておきましょう。すると

./build.sh

で実行でき、main.cppをコンパイルした実行ファイルa.outを生成してくれるはずです。

a.out

./a.out

で実行できますが、毎回これを打って入力を与えて、とするのはやや面倒です。なので、io.shでできるようにします。

code io.sh
chmod +x io.sh

io.shの中身は以下の通りにします。

#! /bin/bash
cd ~/competitive/
./a.out < in.txt > out.txt

io.shは、in.txtの内容を標準入力として受け取ってa.outを実行し、標準出力をout.txtに書き込みます。

in.txtout.txtを作成します。

code in.txt
code out.txt

in.txtout.txtは常に表示しているほうが便利なので、レイアウトを変えます。
View > Editor Layout > Two Rows Rightを押下し、in.txtを右上のウィンドウに、out.txtを右下のウィンドウで開きます。逆でもよいです。

./io.shを実行した例を以下に示します。
image.png

これで定義完了…なのですが、./build.shとか毎回打つのは面倒ですね?短縮します。

code ~/.bashrc

~/.bashrcの一番下に、次の内容を追記します。

alias bd='/home/[ユーザ名]/competitive/sh/build.sh'
alias io='/home/[ユーザ名]/competitive/sh/io.sh'

私の場合は/home/sora/competitive/sh/build.shなどですね。

alias ooo='xxx'oooxxxに置き換えます。
C++の#defineマクロを想像するとよいです。
bdbuildioin/outからとっています8

追記したら、以下を実行するかVSCodeを再起動して反映させます。

source ~/.bashrc

ここまで正常に進んでいれば、

bd
io

でコンパイルと実行ができるはずです。楽ですね。

おわり

これで当記事での環境構築は完了です。おつかれさまでした。

wsl --installが使えない環境で初めてやったときは本当に大変だった記憶があるんですが、今回は結構楽でした。この記事で次回以降はもっと楽になるとうれしいです。

  1. 当記事執筆時点での、AtCoderで使用できるC++の最新バージョン (C++23も選択できますが、AtCoderの環境だと実質20なので…)

  2. 「ディレクトリ」はWindows等の「フォルダ」に相当する概念です。

  3. というか優先度の都合などがあるのか、他の設定は反映されない?

  4. 「はじめに」の項で触れたとおり、別に作業ディレクトリ直下に置いても構いません。どっちのほうがいいのかは私にはわかりかねます。

  5. サムネかわいいですね

  6. <bits/stdc++.h>は元来プリコンパイルすることを前提に作られていたはずです

  7. とりあえずgrepより正規表現を用いた方がよさそうな気はしますが、どうなんでしょう

  8. bとかiとか、一文字にしたほうが早くなりますが、なんか一文字にまで踏み込む勇気は出ませんでした(?)

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?