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かコマンドプロンプトを「管理者として実行」で開いて、以下のコマンドを実行します。

Windows PowerShell (管理者として実行)
wsl --install

その後PCを再起動します。

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

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

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

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

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

image.png

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

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

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

こちらの記事の手順に沿って、gcc及びg++の別バージョンをインストールし、update-alternativesコマンドの設定もしておきましょう。
これによりC++20環境を利用できます。

具体的には以下の手順を実行します。
12の部分は適宜最新のバージョンの数値に置き換えてください(詳しくは後述)。

Ubuntu
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のターミナルを一旦終了しておきましょう。

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

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

image.png

一度VSCodeを終了します。
Linuxのターミナルを起動し、以下を実行して競プロ用のディレクトリを作成します。

Ubuntu
mkdir competitive
code competitive

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

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

image.png

C++の設定

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

image.png

インストールしたらVSCodeを再起動してください。

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

c_cpp_properties.jsonに以下の内容を記述します。

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
}
初期状態とのDiff
c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**",             
+               "~/competitive/ac-library"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c17",
-           "cppStandard": "gnu++14",
+           "cppStandard": "gnu++20",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

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

ついでに、画面左上のFile>Preferences>SettingsでVSCode全般の設定ができることを知っておきましょう。
設定に関しては人それぞれなので、使いながら適宜設定していけばよいです。基本的に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

AtCoder Libraryの保存場所はLinux > Ubuntu > home > [ユーザ名] > [作業ディレクトリ] > [AtCoder Libraryを入れるディレクトリ]です4
以下では、[AtCoder Libraryを入れるディレクトリ]のディレクトリ名をac-libraryにしたと仮定して話を進めます。

予めac-libraryディレクトリを作成しておきます。

Ubuntu
cd ~/competitive
mkdir ac-library

さて、AtCoder Libraryをダウンロードします。
こちらのGitHubから、画面中央-右上あたりの「Code」>「Download ZIP」を押下します。

image.png

ダウンロードしたzipファイルを展開し、Linux側に移します。
WSLであれば、Windows標準の「エクスプローラー」からLinux環境のファイルにも干渉できるので、普通にコピペなりドラッグアンドドロップなりをするとよいです。

なお、展開したフォルダ(ac-library-master)内にはそこそこの数のファイルとフォルダが入っていたと思いますが、ac-libraryディレクトリに移しておくべきなのはatcoderexpander.pyくらいだと思います。

あとはc_cpp_properties.jsonincludePathにac-libraryのパスを渡して、IntelliSenseに認識させておきます(この工程は既にやっています)。
includePathがこのようになっていればよいです。

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

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

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

参考:5

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

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

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

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

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

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

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

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

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

Ubuntu
ls

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

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

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

実行用ShellScriptの作成

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

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

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

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

Ubuntu
cd ~/competitive
mkdir sh
cd sh

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

Ubuntu
code build.sh

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

build.sh
#!/bin/bash

cd ~/competitive/
# ソースファイルの決定
SOURCE_FILE="${1:-main.cpp}" # 引数が無い場合はmain.cppを使用

# "atcoder"の出現回数をカウント
ATCODER_COUNT=$(grep -o "atcoder" "$SOURCE_FILE" | wc -l)

# コンパイルオプションの決定
CXX_FLAGS="-std=gnu++20 -O2 -Wall -Wextra"
if [ "$ATCODER_COUNT" -ge 2 ]; then
    CXX_FLAGS+=" -I./ac-library"
fi

# コンパイル実行
g++ $CXX_FLAGS "$SOURCE_FILE"

以下の機能を実現しています。

  • 任意の.cppファイルをコンパイルする (初期値はmain.cpp)
  • ソースファイル内に"atcoder"が2つ以上含まれているならAtCoder Libraryに対応したコンパイルオプションへ変更する

保存したら、

Ubuntu
chmod +x ./build.sh

で実行権限を与えておきましょう。すると (カレントディレクトリが./competitiveとして)

./sh/build.sh

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

build.shの凡例
./sh/build.sh      # main.cppをコンパイル
./sh/build.sh a    # a.cppをコンパイル

a.out

./a.out

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

Ubuntu
code io.sh
chmod +x io.sh

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

io.sh
#!/bin/bash

cd ~/competitive/
if [ $# -eq 0 ]; then
    ./a.out < in.txt > out.txt
elif [ "$1" == "term" ]; then
    ./a.out < in.txt
else
    ./a.out < in.txt > "$1.txt"
fi

io.shは、in.txtの内容を標準入力として受け取ってa.outを実行し、標準出力をout.txtに書き込みます(ファイル入出力)。
また、引数としてファイル名を渡せば標準出力を[ファイル名].txtに書き込みます。
termを引数にすると標準出力をターミナルに書き込みます(標準出力)。

io.shの凡例
./sh/io.sh             # out.txtに書き込み
./sh/io.sh memo        # memo.txtに書き込み
./sh/io.sh term        # ターミナルに出力

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

Ubuntu
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とか毎回打つのは結局面倒ですね?短縮します。

Ubuntu
code ~/.bashrc

~/.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からとっています7

追記したら、以下を実行するかVSCodeを再起動して反映させます(再起動の方がよいかも?)。

Ubuntu
source ~/.bashrc

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

Ubuntu
bd
io

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

旧版のsh/

拙著のshファイルを一応残しておきます。
汚い見た目で、絶対これもっとうまく書けるんだろうとは思っていたんですが、ChatGPTに投げたら見事に綺麗になって帰ってきました。そんな…

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
io.sh
#! /bin/bash
cd ~/competitive/
if [ $# == 0 ]; then
    ./a.out < in.txt > out.txt
    exit 0
fi
if [ $1 == "terminal" ]; then
    ./a.out < in.txt
    exit 0
fi
./a.out < in.txt > $1.txt

おわり

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

私はまだ導入していませんが、online-judge-toolsatcoder-cliなど便利なコマンドラインツールもあるので、もっと利便性を高めたい人は調べてみると良いと思います。

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


これはただの余談なのですが、なんか現時点「競プロ 環境構築」でGoogle検索すると一番上にこの記事が出てくるらしいですね。「atcoder 環境構築」でも3番目に出てきています。
多分私が一番驚いてる。これそんなに上げてもらっていいのか?(困惑)
私用のメモ程度に書いた記事のつもりでしたが、ご愛読いただきありがたい限りです。

image.png

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

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

  3. というか優先度の都合などがあるのか、他の設定は反映されない? よくわかっていません…

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

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

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

  7. 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?