はじめに
この記事は自分が実際にmac上にc++の競プロ用環境を構築した一連の流れを記したものです。
環境構築に関する記事はすでに多く存在しますが、環境構築は人によって様々なパターンがあるので、一例として参考にしていただけるとありがたいです。
今回は特に初心者向けに丁寧に説明をしているので長くなりますが挫けず最後まで頑張ってください!
また、記事に間違っている部分を見つけた方や、自分と同じようにやったけどエラーが出た方、わかりづらいところがあった方は気軽に質問、コメントしてください!
開発環境
・macOS (Sonoma14)
・vscode
・homebrew
・gcc
目標
vscodeを操作するだけでc++で書かれたファイルをコンパイル、実行できるようにする。
1. Homebrewのインストール
まず、Homebrewをインストールします。
Homebrewとは、macOSやLinux向けのパッケージマネージャーです。
Homebrewを用いることで様々なソフトウェアを管理することができ、インストール、アンインストール、アップデートなどが簡単に行えるようになります。
macを用いている人は基本Homebrewを用いていると思います。
ターミナルを開いて以下のコマンドを入力することで既にインストールされているか確認します。Homebrewのバージョン情報が出力されたら既にインストールされています。(今後%
から始まるコマンドはターミナルへの入力を意味します。)
% brew --version
私の場合は過去にインストールをしていたのでここではインストールの手順は割愛しますが、以下の記事などを参考にしてください。
2. gccのインストール
続いて、Homebrewを用いてgcc
をインストールします。
gcc
とは様々な言語のコンパイラを含んだパッケージで、c言語のコンパイルに用いられるgcc
コンパイラ(パッケージ名と同じでややこしいですね)、c++のコンパイルに用いられるg++
コンパイラなどが含まれています。
今回の一番の目当てはg++
ですが、同時にgcc
もインストールされるのでついでにgcc
も使えるようにしていきます。
ちなみに、macにはもともとclang
というコンパイラが入っており、そちらを用いても特に問題がありません。しかし、競プロを行う人の多くはg++をわざわざインストールして使っています。その最も大きな理由は、bits/stdc++.h
というヘッダーファイルがclang
では使えないからです。
このヘッダーファイルはC++の標準ライブラリを一括でインクルードするためのものです。このヘッダーファイル自体は非標準で、以下のような欠点があるため推奨されていません。
- 標準ライブラリを一括でインクルードするため実際に使われているライブラリがわかりにくい
- 余計なライブラリもインクルードするためコンパイル時間が増加する可能性がある
- g++のような環境でしか対応されていない(Clangでは使えない)
しかし、シンプルなコードで標準ライブラリをインクルードできるため競技プログラミングではよく使われています。
以下のコマンドをターミナルで入力してgccパッケージをインストールします。
% brew install gcc
3. gccパッケージの確認
% brew list
もしくは
% brew list | grep gcc
でgccがインストールできたか確認します。
brew list
でHomebrewを通してインストールされたパッケージ一覧が表示されます。
brew list | grep gcc
でリストの内からgcc
と名前に入っているパッケージが表示されます。
どちらにせよgcc
が表示されたらインストールできています。
4. gcc,g++の確認
Homebrewでgccパッケージをインストールすると、/usr/local/bin
にgccとg++のシンボリックリンクが配置されます。シンボリックリンクとは他のファイルやディレクトリを参照する特殊なファイルで、このファイルを通して、別の場所にある本物のファイルにアクセスできます。
以下のコマンドで/usr/local/bin
に保存されているファイルの一覧をみるとgcc-{version}
, g++-{version}
という形で保存されていることがわかります。
% ls /usr/local/bin
本物のファイルは別の場所(/usr/local/Cellar
)に保存されています。
以下のコマンドでシンボリックコマンドが参照している本物の実行ファイルのpathが表示されます。
% ls -l /usr/local/bin | grep g++
出力は以下の通り。
lrwxr-xr-x@ 1 ◯◯◯◯ admin 33 6 23 10:37 g++-14 -> ../Cellar/gcc/14.1.0_1/bin/g++-14
lrwxr-xr-x@ 1 ◯◯◯◯ admin 55 6 23 10:37 x86_64-apple-darwin23-g++-14 -> ../Cellar/gcc/14.1.0_1/bin/x86_64-apple-darwin23-g++-14
これは、/usr/local/bin
にあるg++-14
(バージョンは人による)というファイルは../Cellar/gcc/14.1.0_1/bin/g++-14
というファイルへのシンボルリンクであることを意味しています。
以上より、Homebrewでgcc, g++コンパイラがインストールされ、それらのシンボリックリンクが/usr/local/bin
に配置されていることが確認できました。
これにより、gcc-14
やg++-14
といったコマンドでgccコンパイラとg++コンパイラを用いることができるようになった。具体的には、test.cpp
というファイルを作成した場合、ターミナルでそのファイルがあるディレクトリまで行き、以下のようなコマンドを入力するとファイルのコンパイルを行うことができ、デフォルトでa.out
という名前の実行ファイルが作成される。
% g++-14 test.cpp
さらに以下のコマンドで実行ファイルの実行ができる。
% ./a.out
ここまでで、一応gcc
とg++
を用いてコンパイルを行うことができるようになりました。ここで辞めても特に問題はありませんが、より便利な環境をこの先で構築していきます。
5. gcc, g++コマンドを使えるようにする(推奨)
ここまでの内容だと、コンパイラを用いるときgcc-14
やg++-14
といったバージョンまで含めたコマンドを用いる必要があります。
gcc
やg++
といったシンプルなコマンドを用いてコンパイルを行えるようにしましょう。
macの場合はgcc
やg++
といったシンプルなコマンドを用いるとなぜかデフォルトで入っているClangというコンパイラが使われてしまう設定になっています。
実際に以下のコマンドを用いるとgcc, g++コマンドで参照されるファイルのpathが表示されます。
% which gcc
% which g++
出力は以下の通りです。
/usr/bin/gcc
/usr/bin/g++
これは先ほどインストールしたgcc,g++のpathと異なることがわかります。
以下のコマンド(g++でも同様)で中身を見てみましょう。
% gcc -v
出力は以下の通り。
Apple clang version 15.0.0 (clang-1500.1.0.2.5)
Target: arm64-apple-darwin23.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
実際に実行されるコンパイラはclangであることがわかります。
ではどのようにしてgcc
,g++
コマンドで先ほどインストールされたgcc,g++が実行されるようにするかというと、clangのパスよりも参照する優先度が高い位置に新たにgcc
,g++
という名前のシンボルリンクを作成し、インストールしたgccのコンパイラを参照するようにすればいいのです。
具体的には/usr/local/bin
にgcc
やg++
というリンクを作成し、そのリンク先を/usr/local/bin
にあるgcc-14
やg++-14
といったシンボルリンクにして二段階で参照するか、直接../Cellar/gcc/14.1.0_1/bin/gcc-14
や../Cellar/gcc/14.1.0_1/bin/g++-14
という実行ファイルにするかのどちらかを行えばいいです。
参考にしたサイトでは前者を用いていますが、後者の方がシンプルに感じるため後者を試みます。
以下のコマンドで新しくシンボルリンクを作成できます。
% sudo ln -s ../Cellar/gcc/14.1.0_1/bin/gcc-14 /usr/local/bin/gcc
% sudo ln -s ../Cellar/gcc/14.1.0_1/bin/g++-14 /usr/local/bin/g++
以上により/usr/local/bin
に新しく、インストールしたgcc,g++へのシンボルリンクが作成されました。
人によってはこれだけでgcc
やg++
というコマンドで新しいコンパイラを使用できるようになるでしょう。
しかし、まだ/usr/bin
にある古いgcc, g++と/usr/local/bin
にある新しいシンボルリンクが共存しており、人によっては古いほうが使われてしまう。これは/usr/bin
のpathの優先順位 が/usr/local/bin
のpathの優先順位より高いためです。従って/usr/local/bin
の優先順位を上げることで新しいコンパイラを参照するようにしましょう。
以下のコマンドで.zshrc
の最終行にexport PATH="/usr/local/bin:$PATH"
と書き加えることができる(zshを用いている場合)。.zshrc
とはターミナル内で使われているzsh
というシェルの設定を書くファイルです。
% echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.zshrc
これにより/usr/local/bin
が PATH
の先頭に追加され、そのディレクトリ内の実行可能ファイルが優先して実行されるようになります。
最後に.zshrc
に加えた変更を以下のコマンドで反映します。
% source ~/.zshrc
pathの優先度は以下のコマンドで確認できる。
% echo $PATH
これで出力されるpathの一覧のうち先(左)に書かれているものの優先度が高いです。/usr/local/bin
が一番最初に書かれていれば問題ありません。
以上までで、gcc
, g++
コマンドを用いるとインストールされたコンパイラが実行されるようになっているはずです。
以下のコマンドで確認することができま。
% which gcc
% which g++
それぞれ以下のような出力が得られて、インストールしたコンパイラが実行されることが確認できました。
/usr/local/bin/gcc
/usr/local/bin/g++
念のためにgcc
, g++
コマンドで実行されるコンパイラのバージョンを以下のコマンドで確認する。
% gcc --version
% g++ --version
すると以下のような出力が得られ、homebrewでインストールしたコンパイラであることがわかる。
gcc (Homebrew GCC 14.1.0_1) 14.1.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
g++ (Homebrew GCC 14.1.0_1) 14.1.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
4. ターミナル上での実行結果の確認
以上まででgccが使えるようになったので試しに以下のコードを実行しました。
#include<bits/stdc++.h>
using namespace std;
int main () {
cout << "Hello World!" << endl;
}
実行コマンドは以下。
% g++ test.cpp && ./a.out
初学者のために簡単に上記のコマンドの説明をしておきます。
g++ test.cpp
:g++コンパイラでtest.cppというc++ファイルをコンパイル。成功するとデフォルトでa.outという実行ファイルが作成される。
&&
:左側のコマンド(コンパイル)が成功した場合のみ右側のコマンドを実行。
./a.out
:a.outというファイルを実行する。
以下の出力が得られたため、正しくコンパイルされていることが確認できました。
Hello World!
ちなみに、人によってはここで以下のようなエラーが出ることがあるみたいです。
In file included from /usr/local/Cellar/gcc/14.1.0_1/include/c++/14/x86_64-apple-darwin23/bits/stdc++.h:42,
from test.cpp:1:
/usr/local/Cellar/gcc/14.1.0_1/include/c++/14/cstdlib:79:15: fatal error: stdlib.h: No such file or directory
79 | #include_next <stdlib.h>
| ^~~~~~~~~~
compilation terminated.
これはヘッダーファイルを参照するパスの設定がうまくできていないためです。比較的簡単に改善できますが、長くなるのでここでは割愛します。このエラーが出た方はコメントしてください!
ここまででターミナル上でc++ファイルのコンパイル、実行が行えるようになりました!
必須なのはここまでです。
ここから先はvscodeを用いてより便利な環境を構築していきます。
5. vscodeへの拡張機能のインストール
ここまでで、gcc, g++コンパイラを用いてc, c++ファイルのコンパイル、実行をターミナル上で行うことができるようになりました。これで終わりにしても良いですが、せっかくなのでvscode上でより楽に実行できる環境を構築しましょう。
まず、vscodeをインストールしていない人は先に以下の記事などを参考にvscodeをインストールしてください!
vscodeはおそらく世界で最もよく使われているテキストエディタです。
多くの言語の場合、vscodeを用いると簡単にコードが書けたりデバッグできるので便利です。
ではvscodeはインストール済みとして進めていきます。
まず、以下の拡張機能をインストールします。
- C/C++
- Code Runner(vscodeを操作するだけで簡単にコードの実行まで行えるようになる)
- CodeLLDB(C,C++などの言語のデバッグをサポートする)
拡張機能のインストールはvscode左端のタブで正方形四つのマークのところから検索してインストールできます。
6. Code Runnerの設定
続いて、Code Runnerの設定を行なっていきます。
Code Runnerを用いると、vscode内の実行ボタンをクリックするだけで統合ターミナル内でファイルの実行ができるようになります。統合ターミナルとは、vscodeの画面内に表示することができるターミナルのことです。この機能のおかげで、別でターミナルを開かなくてもvscode内でターミナルを開いてファイルの実行などを行うことができます。
必要な設定は一つだけです。
まず、拡張機能のCode Runnerのページの歯車を押して設定画面を開きます。
続いてこの中のRun in Terminal
という項目にチェックを入れます。
これで、実行ボタン一つで統合ターミナルを通してファイルの実行を行うことができるようになりました。
7. JSONファイルによる設定
続いてvscodeでc,c++ファイルのコンパイルと実行、デバッグを行うためにいくつかの設定を行います。vscodeでは、設定は.json
という拡張子のファイルに記述されて保存されています。
具体的には以下の2つのファイルの編集(まだ無い場合は作成)を行います。
- setting.json
- c_cpp_properties.json
7.1 setting.json
そもそも、vscodeの設定にはいくつかのレベルがあります。代表的なのは以下の三つです。
- ユーザ設定
- ワークスペース設定
- フォルダ設定
ユーザ設定とは基本的にvscodeを使用するときに常に適用される設定です。以下の位置に設定ファイルが保存されます。
/Users/{ユーザ名}/Library/Application Support/Code/User
まず、ここにあるsetting.json
というファイルを編集します。setting.json
を開くにはまずcommand + shift + P
を押すことでコマンドパレットを開きます。そしてコマンドパレットにsetting
と入力すると基本設定:ユーザ設定を開く
というボタンが出るのでクリックしてください。
ここに書いてある内容は人それぞれですが、以下の二つの項目が書いてあるはずです。
"code-runner.runInTerminal": true
"code-runner.executorMap":
"code-runner.runInTerminal": true
は、先ほどCode Runnerの設定を行なった際に自動で記述された行になります。
今から編集するのは"code-runner.executorMap":
という項目です。この項目には{}
が続いていて、"{言語名}":"~~~~"
のような行がいくつか書いてあると思います。
この項目は、Code Runnerに関する設定で、vscode上で実行ボタンを押したとき、実際にどのようなコマンドを統合ターミナル内で実行するかを指定する設定がファイルの言語ごとに書かれています。
つまり、cppで書かれたファイルを開いているときに実行ボタンを押したら以下のコマンドが自動でターミナルに入力されるように設定すれば、いちいち入力する必要がなくなるということです。
% g++ test.cpp && ./a.out
ではsetting.json
を書き換えていきましょう。
方法は簡単です。"cpp":
という行がすでにあればその行を編集し、なければ新しく書くという形で、以下の行を書いてください。
"cpp": "cd $dir && g++ $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
先ほど示したg++ test.cpp && ./a.out
というコマンドより長くなっていると思いますが、こちらの方より詳しく指定しているだけです。このコマンドの説明を以下の通りです。
-
cd $dir
:
現在開いているファイルが存在しているディレクトリに移動する。($dir
は開いているファイルが存在するディレクトリのパスを示します。) -
&&
:
直前のコマンドが成功した時のみ次のコマンドを実行する。 -
g++ $fileName
g++
で現在開いているファイルをコンパイルする。 -
-o $fileNameWithoutExt
:
-o
で生成される実行ファイルの名前を指定する。このコマンドがなければデフォルトではa.out
という名前で生成される。-o $fileNameWithoutExt
でソースファイルから拡張子(.cpp)を消した名前の実行ファイルを生成する。 -
$dir$fileNameWithoutExt"
:
生成した実行ファイルを実行する。
これで、c++ファイルを開いているときにvscode上で実行ボタンを押すと統合ターミナル上でcd $dir && g++ $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt
というコマンドが自動的に入力されてソースファイルのコンパイルと実行が行われるようになりました。
実際に以下のようにvscodeでtest.cpp
を開いて右上の三角ボタンから実行
(Run Code
)を押すと下の統合ターミナルにcd {ディレクトリパス} && g++ {ファイル名.cpp}-o {ファイル名} && {ディレクトリパス+ファイル名}
というコマンドが入力されてHello World!
と出力されました。
7.2 c_cpp_properties.json(任意)
続いて、c_cpp_properties.json
という設定ファイルを編集していきます。
ここから先で扱う三つのjsonファイル(c_cpp_properties.json
、task.json
、launch.json
)はどれも基本的にワークスペース設定として扱われます。
つまり、現在開いているワークスペースのみで適用される設定のため、異なるワークスペースを開いた際には適用されません。
人によっては不便に感じるかもしれませんが、全体の設定にしてしまうと後から困ることもあるので、ワークスペース設定で困らない場合はワークスペース設定にすることをお勧めします。
今回の場合は競プロ用の環境設定を想定しているので、競プロ用のワークスペースを作って、全てのコードをこのワークスペースで書けば設定が適用されるので問題ないと思います。
ワークスペース設定は{現在開いているワークスペース}/.vscode
というディレクトリに保存されます。.vscode
というディレクトリはvscodeでワークスペースを開くと自動で作成されます。
.
で始まるフォルダやファイルは隠しフォルダ、隠しファイルと呼ばれ、ファインダーではデフォルトで表示されないようになっているので、ファインダーで今開いているワークスペースを見ても確認できませんが、確かに存在しています。
では、この中のc_cpp_properties.json
というファイルを編集していきましょう。
このファイルは、vscodeのc/c++という拡張機能に関する設定を行うファイルです。
先に断っておくと、このファイルを編集しなくても、先ほど確認したようにファイルのコンパイルと実行はできるのでこの作業は任意です。
現状、先ほどのtest.cpp
を開いたときに赤い波線が出てしまう人はここの設定を編集することで改善されます。
従って、波線が出て尚且つそれが気になる人はこの設定を行いましょう。
まず、c_cpp_properties.jsonを開きます。
先ほどと同じようにcommand+shift+P
でコマンドパレットを開き、c/c++:edit configurations
と打つとjsonファイルを開くことができます。
この中の"compilerPath":
という項目がclang
などを指している場合、ここをインストールしたg++
のパスに書き換えます。
これによりvscodeが正しいコンパイラを参照するようになり、インクルードするヘッダーなどのパスも自動的に検出され、ソースコードから赤線が消えます。
これでもソースコードのインクルードの行に赤線が残る人は、"includePath"
のヘッダーファイルがあるパスを直接書いてみてください。
私の場合はコンパイラパスを書き換えるだけでうまくいきました。
私のc_cpp_properties.json
は以下の通りです。
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"macFrameworkPath": [
"/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/System/Library/Frameworks"
],
"compilerPath": "/usr/local/bin/g++",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "macos-clang-arm64"
}
],
"version": 4
}
8.最後に
お疲れ様でした!
これでvscodeを用いてc++ファイルのコンパイルと実行ができるようになりました。
いちいち寄り道をして説明をしたので長くなりましたが、皆さんのお役に立てると嬉しいです。
もし、わからない点や間違っている点がありましたらご気軽にコメントしてください!
参考文献