2024年版初心者向けのC++環境構築（Mac + vscode + gcc、競プロ用）

# はじめに
この記事は自分が実際にmac上にc++の競プロ用環境を構築した一連の流れを記したものです。

環境構築に関する記事はすでに多く存在しますが、環境構築は人によって様々なパターンがあるので、一例として参考にしていただけるとありがたいです。

今回は特に初心者向けに丁寧に説明をしているので長くなりますが挫けず最後まで頑張ってください！

また、記事に間違っている部分を見つけた方や、自分と同じようにやったけどエラーが出た方、わかりづらいところがあった方は気軽に質問、コメントしてください！

**開発環境**
・macOS (Sonoma14)
・vscode
・homebrew
・gcc

**目標**
vscodeを操作するだけでc++で書かれたファイルをコンパイル、実行できるようにする。



# 1. Homebrewのインストール
まず、Homebrewをインストールします。
Homebrewとは、macOSやLinux向けのパッケージマネージャーです。
Homebrewを用いることで様々なソフトウェアを管理することができ、インストール、アンインストール、アップデートなどが簡単に行えるようになります。
macを用いている人は基本Homebrewを用いていると思います。

ターミナルを開いて以下のコマンドを入力することで既にインストールされているか確認します。Homebrewのバージョン情報が出力されたら既にインストールされています。（今後`%`から始まるコマンドはターミナルへの入力を意味します。）
```zsh
% brew --version
```
私の場合は過去にインストールをしていたのでここではインストールの手順は割愛しますが、以下の記事などを参考にしてください。

https://qiita.com/Meycha/items/2a07fcd7920d3c6af4fa

    
# 2. gccのインストール
続いて、Homebrewを用いて`gcc`をインストールします。
`gcc`とは様々な言語のコンパイラを含んだパッケージで、c言語のコンパイルに用いられる`gcc`コンパイラ（パッケージ名と同じでややこしいですね）、c++のコンパイルに用いられる`g++`コンパイラなどが含まれています。
今回の一番の目当ては`g++`ですが、同時に`gcc`もインストールされるのでついでに`gcc`も使えるようにしていきます。
ちなみに、macにはもともと`clang`というコンパイラが入っており、そちらを用いても特に問題がありません。しかし、競プロを行う人の多くはg++をわざわざインストールして使っています。その最も大きな理由は、`bits/stdc++.h`というヘッダーファイルが`clang`では使えないからです。
このヘッダーファイルはC++の標準ライブラリを一括でインクルードするためのものです。このヘッダーファイル自体は非標準で、以下のような欠点があるため推奨されていません。

- 標準ライブラリを一括でインクルードするため実際に使われているライブラリがわかりにくい
- 余計なライブラリもインクルードするためコンパイル時間が増加する可能性がある
- g++のような環境でしか対応されていない（Clangでは使えない）

しかし、シンプルなコードで標準ライブラリをインクルードできるため競技プログラミングではよく使われています。

以下のコマンドをターミナルで入力してgccパッケージをインストールします。
```zsh
% brew install gcc
```


# 3. gccパッケージの確認
    
```zsh
% brew list
```

もしくは

```zsh
% brew list | grep gcc
```

でgccがインストールできたか確認します。

`brew list` でHomebrewを通してインストールされたパッケージ一覧が表示されます。

`brew list | grep gcc` でリストの内から`gcc`と名前に入っているパッケージが表示されます。

どちらにせよ`gcc` が表示されたらインストールできています。
    
# 4. gcc,g++の確認
    
Homebrewでgccパッケージをインストールすると、`/usr/local/bin`にgccとg++の[シンボリックリンク](https://envader.plus/course/16/scenario/1025)が配置されます。シンボリックリンクとは他のファイルやディレクトリを参照する特殊なファイルで、このファイルを通して、別の場所にある本物のファイルにアクセスできます。

以下のコマンドで`/usr/local/bin` に保存されているファイルの一覧をみると`gcc-{version}`, `g++-{version}`という形で保存されていることがわかります。

```zsh
% ls /usr/local/bin
```

本物のファイルは別の場所(`/usr/local/Cellar` )に保存されています。

以下のコマンドでシンボリックコマンドが参照している本物の実行ファイルのpathが表示されます。

```zsh
% ls -l /usr/local/bin | grep g++
```

出力は以下の通り。

```zsh
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`という名前の実行ファイルが作成される。
```zsh
% g++-14 test.cpp
```
さらに以下のコマンドで実行ファイルの実行ができる。
```zsh
% ./a.out
```

ここまでで、一応`gcc`と`g++`を用いてコンパイルを行うことができるようになりました。ここで辞めても特に問題はありませんが、より便利な環境をこの先で構築していきます。

# 5. gcc, g++コマンドを使えるようにする（推奨）

ここまでの内容だと、コンパイラを用いるとき`gcc-14`や`g++-14` といったバージョンまで含めたコマンドを用いる必要があります。

`gcc`や`g++` といったシンプルなコマンドを用いてコンパイルを行えるようにしましょう。

macの場合は`gcc`や`g++` といったシンプルなコマンドを用いるとなぜかデフォルトで入っているClangというコンパイラが使われてしまう設定になっています。

実際に以下のコマンドを用いるとgcc, g++コマンドで参照されるファイルのpathが表示されます。

```zsh
% which gcc
```

```zsh
% which g++
```

出力は以下の通りです。

```zsh
/usr/bin/gcc
```

```zsh
/usr/bin/g++
```

これは先ほどインストールしたgcc,g++のpathと異なることがわかります。

以下のコマンド（g++でも同様）で中身を見てみましょう。

```zsh
% gcc -v
```

出力は以下の通り。

```zsh
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` という実行ファイルにするかのどちらかを行えばいいです。

参考にしたサイトでは前者を用いていますが、後者の方がシンプルに感じるため後者を試みます。

以下のコマンドで新しくシンボルリンクを作成できます。

```zsh
% 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`というシェルの設定を書くファイルです。

```zsh
% echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.zshrc 
```

これにより`/usr/local/bin` が `PATH` の先頭に追加され、そのディレクトリ内の実行可能ファイルが優先して実行されるようになります。

最後に`.zshrc` に加えた変更を以下のコマンドで反映します。

```zsh
% source ~/.zshrc　
```

pathの優先度は以下のコマンドで確認できる。

```zsh
% echo $PATH
```

これで出力されるpathの一覧のうち先（左）に書かれているものの優先度が高いです。`/usr/local/bin` が一番最初に書かれていれば問題ありません。

以上までで、`gcc`, `g++` コマンドを用いるとインストールされたコンパイラが実行されるようになっているはずです。

以下のコマンドで確認することができま。

```zsh
% which gcc
% which g++
```

それぞれ以下のような出力が得られて、インストールしたコンパイラが実行されることが確認できました。

```zsh
/usr/local/bin/gcc
```

```zsh
/usr/local/bin/g++
```

念のために`gcc`, `g++` コマンドで実行されるコンパイラのバージョンを以下のコマンドで確認する。

```zsh
% gcc --version
% g++ --version
```

すると以下のような出力が得られ、homebrewでインストールしたコンパイラであることがわかる。

```zsh
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.
```

```zsh
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が使えるようになったので試しに以下のコードを実行しました。

```cpp:test.cpp
#include<bits/stdc++.h>
using namespace std;

int main () {
  cout << "Hello World!" << endl;
}
```


実行コマンドは以下。

```zsh
% g++ test.cpp && ./a.out
```

初学者のために簡単に上記のコマンドの説明をしておきます。

`g++ test.cpp` ：g++コンパイラでtest.cppというc++ファイルをコンパイル。成功するとデフォルトでa.outという実行ファイルが作成される。

`&&` ：左側のコマンド（コンパイル）が成功した場合のみ右側のコマンドを実行。

`./a.out` ：a.outというファイルを実行する。

以下の出力が得られたため、正しくコンパイルされていることが確認できました。

```zsh
Hello World!
```
ちなみに、人によってはここで以下のようなエラーが出ることがあるみたいです。
```zsh
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を用いると簡単にコードが書けたりデバッグできるので便利です。

https://qiita.com/watamura/items/51c70fbb848e5f956fd6

ではvscodeはインストール済みとして進めていきます。
まず、以下の拡張機能をインストールします。

- C/C++
- Code Runner（vscodeを操作するだけで簡単にコードの実行まで行えるようになる）
- CodeLLDB（C,C++などの言語のデバッグをサポートする）

拡張機能のインストールはvscode左端のタブで正方形四つのマークのところから検索してインストールできます。

![スクリーンショット 2024-07-14 16.28.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826524/961650e3-b6b6-b234-d1e5-91464db9707e.png)

# 6. Code Runnerの設定
続いて、Code Runnerの設定を行なっていきます。
Code Runnerを用いると、vscode内の実行ボタンをクリックするだけで統合ターミナル内でファイルの実行ができるようになります。統合ターミナルとは、vscodeの画面内に表示することができるターミナルのことです。この機能のおかげで、別でターミナルを開かなくてもvscode内でターミナルを開いてファイルの実行などを行うことができます。

必要な設定は一つだけです。
まず、拡張機能のCode Runnerのページの歯車を押して設定画面を開きます。
![スクリーンショット 2024-07-14 17.04.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826524/54acc503-3b8c-6bfc-86a0-36974cc46109.png)
続いてこの中の`Run in Terminal`という項目にチェックを入れます。
![スクリーンショット 2024-07-14 17.14.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826524/a7d0fea3-a2e7-6cbb-d99c-0594fa0da58c.png)
これで、実行ボタン一つで統合ターミナルを通してファイルの実行を行うことができるようになりました。
# 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`と入力すると`基本設定：ユーザ設定を開く`というボタンが出るのでクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826524/5b4e75ed-50c2-75a5-726c-8d831ddae0cd.png)

ここに書いてある内容は人それぞれですが、以下の二つの項目が書いてあるはずです。
- `"code-runner.runInTerminal": true`
- `"code-runner.executorMap":`

`"code-runner.runInTerminal": true`は、先ほどCode Runnerの設定を行なった際に自動で記述された行になります。

今から編集するのは`"code-runner.executorMap":`という項目です。この項目には`{}`が続いていて、`"{言語名}":"~~~~"`のような行がいくつか書いてあると思います。
この項目は、Code Runnerに関する設定で、vscode上で実行ボタンを押したとき、実際にどのようなコマンドを統合ターミナル内で実行するかを指定する設定がファイルの言語ごとに書かれています。

つまり、cppで書かれたファイルを開いているときに実行ボタンを押したら以下のコマンドが自動でターミナルに入力されるように設定すれば、いちいち入力する必要がなくなるということです。
```zsh
% g++ test.cpp && ./a.out
```

では`setting.json`を書き換えていきましょう。
方法は簡単です。`"cpp":`という行がすでにあればその行を編集し、なければ新しく書くという形で、以下の行を書いてください。

```json
"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!`と出力されました。
![スクリーンショット 2024-07-15 11.27.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3826524/add2307e-f912-dc48-3f60-7c07105cd443.png)

## 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`は以下の通りです。
```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++ファイルのコンパイルと実行ができるようになりました。

いちいち寄り道をして説明をしたので長くなりましたが、皆さんのお役に立てると嬉しいです。
もし、わからない点や間違っている点がありましたらご気軽にコメントしてください！

**参考文献**

https://qiita.com/dhirabayashi/items/fc4327b1771d07502adc

https://qiita.com/watamura/items/51c70fbb848e5f956fd6

https://qiita.com/watamura/items/51c70fbb848e5f956fd6

https://note.com/fuuuuusha/n/n9c16247c49bc

https://qiita.com/EvtHorizonCoder/items/145724e16c1b57ab64eb