VS Codeで最強のC/C++環境を作りたい

# 始めに
C/C++でプログラミングをやるには、その文法の難しさやさまざまな知識を要求されることもそうなんですが、第一にコンパイルする大変さがあります。

ましてや、ちゃんとコンパイルできるとこまでたどり着けても、やはり
1. 編集
2. コンパイル
3. 実行
4. 目的の結果が得られるまで1から3を繰り返す

というのは結構めんどくさいです。

そこで、少しでも楽にこれを回せる環境を作ろうと思います。

:::note info
理解ってる人へ

本稿の目的はビルドとデバッグを高速で回すことです。ある程度開発やってる人はmake使ってるかと思いますがこれとはやることがちょっと違って、ごく小さなプログラムを多数配置する、たとえば学校の課題をこなしたり、AtCoderやAOJを解いていったりするのを想定しています。
:::

# 目標
1. コードを書く
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420671/49f8e090-a0cb-92a9-0498-1a1ce36b243f.png)
1. コンパイル（F5キーを押すだけで自動でコンパイル＆実行）
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420671/1000088d-9ca5-5076-1f6e-9b2be634afd1.png)
1. デバッグも！（コードの実行中に変数の中身などを見ることができたり、変更できたりする。）
![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420671/043c71f2-808f-3a19-56e2-495bb2c468f7.png)

いろいろカスタマイズしているので、UIが多少違うのはご承知おきください。

# 要件
Windows11の人向け。あとちょっと時間かかります。

わからん用語とかはググってどうにかしてね★

# 手順
## WSLのインストール
WSLはWindows上でLinuxというOSを動かせるアプリです。なぜLinuxが必要かといえば、そちらの方がいろいろ便利だからです。最悪なくても行けますが、Windowsでコード書くならゆくゆく入れることになるので今入れとくといいでしょう。

### Windowsのアップデート
とりあえずWindowsのアップデートが来ている場合は、すべて済ませてください。セキュリティアップデートとかあるので、普段からやっておくことをオススメします。

参考
* [Windows Updatesをインストールする](https://support.microsoft.com/ja-jp/windows/windows-%E3%81%AE%E6%9B%B4%E6%96%B0-3c5ae7fc-9fb6-9af1-1984-b5e0412c556a)

### WSL

PowerShellから次を実行してください。
```
wsl --install
```
インストールが終わると、Ubuntu（Linuxの一種）のユーザー登録画面が表示されるので、お好きなユーザー名と打ちやすいパスワードを説明にしたがって入力し、登録を完了してください。

:::note info
* ユーザー名、パスワードは基本ASCII文字のみです。よくわからない場合は、アルファベットのみで。
* パスワードは入力しても表示されません。表示されないだけで打ち込まれてはいるので大丈夫です。
:::

詳しくは、下を読むといいです。

https://qiita.com/zakoken/items/61141df6aeae9e3f8e36

### Ubuntuのセットアップ

これでWSLを仲立ちとしてWindows上にUbuntuがのっかった状態になりました。
今度はこのUbuntuをアップデートします。

Ubuntuを開き、次を実行してください。（一行ずつ）

```bash
sudo apt update -y
# 更新するパッケージを調べ上げる
sudo apt upgrade -y
# 実際に更新する
sudo apt install build-essential gdb
# Debianパッケージのビルドに必要な奴をインストール
```

後は、作業用のディレクトリ（Windowsでのフォルダー）を作っておくとよいでしょう。

```bash
mkdir work
# workディレクトリが作られる。
```

ひとまずWSL関係はこれで完了です。

## VS Codeのインストール
Visual Studio CodeはMicrosoft製のエディターです。さまざまな機能を備えており、[プログラマーの人気エディタランキング](https://www.geeksforgeeks.org/top-code-editors/)では大概1位です。

PowerShellから次を実行してください。（webからもできますが、まあCUIに慣れるために。）

```PowerShell
winget install --id Microsoft.VisualStudioCode --src winget
```

いろいろ指示が出るので、それにしたがってインストールしてください。

そうしたら、Ubuntuを起動して次を実行してください。

```bash
code workdir
```

VS Codeが立ち上がります。

:::note info
codeコマンドが存在しない！とエラーが出た場合は、ひとまず普通にVS Codeを起動し、コマンドパレット（ctrl+shift+Pを同時に押下）を開き、"Shell Command: Install 'code' command in PATH"と打ち込んで出てきたサジェストを実行してください。これで行けるはずです。

いったん閉じて、再度上のコマンドを叩いてください。
:::

## 拡張機能のインストール

起動すると、右下に日本語化するか？とかWSL用の拡張機能を入れるか？とか聞かれますのでとりあえずすべて受け入れてください。

手動でやるなら、画面向かって左のバーにあるブロックが並んだようなアイコンの"Extension"、日本語では「拡張機能」から`ms-ceintl.vscode-language-pack-ja`と打ち込んで出てきたものをインストールすると日本語化されますし、`ms-vscode-remote.vscode-remote-extensionpack`でwslの拡張機能がインストールされます。

加えて、C/C++用の拡張機能をインストールします。例のごとく拡張機能のタブから、`ms-vscode.cpptools-extension-pack`と打ち込んで、出てきたものをインストールしてください。

## 使ってみる

ここまででVS Codeの基本的な立ち上げはできました。
とりあえず使ってみましょう。

画面向かって左上の"Explore"を開いて、タブ上部のバーにある"New File"をクリックするとあたらしいふぁいるが作られますので適当な名前のCファイルを作ります。

（私の場合UIが違ったり先にいろいろ作っちゃってるのでファイルなりディレクトリがいろいろあったりしますが、最初は何もないのでご安心ください。）
!![program1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420671/9f28eeb3-4d0f-ba2b-2458-49ef39c1fa56.png)

世界にあいさつでもしますか。

![intelligence.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420671/34c2781f-f998-e507-dca2-d4516cf05f98.png)

書いているとわかりますが、たとえば画像のように"main"と打つといろいろ候補が表示されるのがわかると思います。この状態で`Enter`を押すと

```C
int main(int argc, char const *argv[])
{
    /* code */
    return 0;
}
```

上のように展開されます。これは「入力補完」や"intelligence"と呼ばれる機能で、単純にタイプ量が減って楽になりますし、変なミスが減ってデバッグも楽になります。

また、文法の誤り、たとえばセミコロンの付け忘れだとか括弧がしっかりと閉じられていないとかの錯誤を表示してくれる「静的解析」の機能も大変有用かと思います。

コンパイルしてみましょう。
エディター上で`Ctrl` + `@`を押下してください。

ターミナルが画面下部に現れます。

```
gcc hello.c
./a.out
Hello, World!
```

（とくにいうことはない）

# Buildの効率化

Msys2とvimを使ってぺちぺちやるよりかはだいぶ楽になるかとは思いますが、正直大差ないですね。セットアップ作業の苦労と見合わないと思います。

ここを効率的にやるのが本稿の本題です。長い前置きになりました。

さて、始めます。

## 結論を急ぐ人向け

https://github.com/Desert-sabaku/vscode_cpp

これを参照して、プロジェクトに適切に配置してやることです。

右上の"Code"という緑色のボタンからZIPを落とせます。

## 使い方

適切に配置できていれば、このような感じになります。

![projectExample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420671/f13c44aa-f97b-e84c-a597-189965ef510d.png)

さて、適当なCのファイルを開き、キーボード上部にある`F5`を押下してください。

![runningExample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420671/72a36f72-afec-36b4-52fc-e36256eb7671.png)

自動で実行、コンパイルしてくれます。

また、デバッガーも扱うことができます。

![debug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2420671/4a82e0b5-681c-9276-7682-220c1c79a0b2.png)

画像のように行番号をクリックして"break point"を貼ってやり（画像では8行目）、この状態で実行してやると、8行目でプログラムが一時停止、この時点での変数の中身が見られます。

`F5`を連打してカウンター用の変数`i`や和を保存する用の変数`sum`の値が変化していくさまが左側のバーにある"Run and Debug"のタブから確認できます。

デバッグについての詳細などは、以下を参照してください。

https://code.visualstudio.com/docs/editor/debugging

どうです、便利でしょう？

## 説明

大まかな仕組みについてざっくりと解説しておきます。

| ファイル名            | 役割                                                         |
| --------------------- | ------------------------------------------------------------ |
| launch.json           | デバッグ実行のための基本設定を記述するファイル               |
| tasks.json            | 実行時に具体的にどのような命令を実行するかを記述するファイル |
| c_cpp_properties.json | CやC++のバージョンやパスなどの情報を記述                     |

Cファイルでビルドを起動すると、launch.jsonが読まれ、そこからtasks.jsonを読み込みます。

以下の抜粋のように、tasks.jsonには具体的なコマンドなどが記述されていますので、挙動をいじりたくなったときはひとまずここを覗いてみるとよいでしょう。

たとえば、"command"の項目に"g++"コマンドが、"args"は言葉通りコマンドに渡される引数ですが、gccを使っている人なら何となく読めると思います。"-o"フラグは出力される実行ファイルの名前を指定することができるものでした。

```json
{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++ debug active file",
            "command": "/usr/bin/g++",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${workspaceFolder}/bin/${fileBasenameNoExtension}.exe",
                "-lm",
                "-W",
                "-Wall",
                "-Wextra",
            ],
        },
    ],
    "version": "2.0.0"
}
```

途中にある`${~~}`という風な文字列は、VS Codeのvariablesです。動的（「実行するとき」の意）に、たとえば${workspaceFolder}ならVS Codeが開いているディレクトリのパスを返してくれます。とにかく、プロジェクトに応じて名前とか場所とか違うと思いますが、そのあたりをいい感じに調整してくれるのです。

## 余談：ちょっとした工夫

私が作成した設定集にはちょっとした工夫が2点ありまして、1点目は、それは実行形式のファイルをbinというディレクトリに隔離していることです。

実際に使っていると、ディレクトリがソースとバイナリでごっちゃに埋め尽くされてUXを著しく下げたので、こうして隔離してやることで「ソースファイルはソースファイルに、実行形式は実行形式に」おいています。

2点目は、ビルド用のtaskとデバッグ用のtaskがわけてあることです。
launch.jsonやtasks.jsonを見てみるとわかりますが、構成が各々2部に大別できることが読み取れるかと思います。

実際に、Run and Debugのタブ上部の歯車マークの左側にある欄をクリックしてみると、サジェストにbuildとdebugの二項目が表示されていることがわかります。

両者の違いは、GCCのwarning設定をonにしているかどうか、です。GCCは"-W"などのフラグを付けてやると、コード中の間違いではないがやめておいた方がいいコードを検知してwarningとして知らせてくれます。

# 終わりに

まあ、書きたいことは書けたので良しとします。なんかあったら書き足します。

今後の展望としては、GCCからClangに移行したいですね。なんかGCCって標準化遅いし最適化の有無でエラーがことなるとかいう妙な挙動とるんですよね。Clangがその辺どうなってるのか全然試してないのでわかりませんが…