VSCode + MinGW-64 で C++ のコードをビルド＆デバッグするまで

# VSCode + MinGW-64 で C++ のコードをビルド＆デバッグするまで

みなさまこんにちは。[ハーツテクノロジー]の山崎です。この記事は仕事の中で得たられた知見によって書かれています。

[ハーツテクノロジー]:https://www.hearts-tech.co.jp/

# どんな話？

プログラマのみなさんはすでに利用しているひとも多いと思われる超絶便利テキストエディタ「Visual Studio Code」の話です。ここでは略して「[VSCode]」と書きます。

このエントリでの話題は、 [VSCode] で C++ のビルドとデバッグができます。しかもフリーのC++である「MinGW-64」を使って！！

そんな話。実際に C++ のコードをデバッグしているところを見たほうが早いですね。こんな感じ。

![MingGW_Debug.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/35de7ea1-291f-c1c9-a294-f5e2ae5bd3fe.gif)

できるようになるには、大きく２つのステップがあって。

1, MinGW-64 のインストール
2, VSCode の設定

この２つです。この２つを乗り越えればハッピープログラミングライフ（なにそれ？）が待っています。以下をご覧くださいませー。

# 1, [MinGW]-64 のインストール

## 1-1, [MinGW] とは

[MinGW]:https://ja.wikipedia.org/wiki/MinGW


>  MinGW（ミン・ジー・ダブリュー、Minimalist GNU for Windows）はGNUツールチェーンのWindows移植版である。MinGWはWindows APIのためのヘッダファイルを含んでおり、フリーのコンパイラであるGCCを、Windowsアプリケーションの開発のために利用できる。

ウィキペディアより引用

ようするに、「Windows でもフリーで使える C++ コンパイラ」のこと。

- mingw-w64　のトップページ

    http://mingw-w64.org/doku.php


## 1-2, ライセンスの話を少し

[MinGW]のウィキペディアによると「GPL」という言葉がある。ここは（私も含め）みなさん気にするところだと思う。しかし、

> なお、MinGWでも、MSYSのライブラリ（msys-1.0.dllやmsys-z.dll）をリンクしている場合、これらのランタイムライブラリライセンスによる制限 (GPL) を受ける[4]。

とも書いてある。この文を逆に解釈すると「MSYSのライブラリ（msys-1.0.dllやmsys-z.dll）をリンクしなければ、GPLの制限は受けない」と読める。
果たして、この解釈でよいのか？私には判断できない。

詳しいひとからのコメントを求めたい。よろしくお願いします。



## 1-3, ダウンロード

- ダウンロードのページ

    http://mingw-w64.org/doku.php/download

    ![screen1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/b763eccf-e941-03e7-9340-6d458e256882.png)


- ダウンロードのリンクをクリック

    ![screen2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/8f5e0850-8b73-fd62-9a33-e7e9c33fd7c5.png)


- ダウンロードが開始され、ローカルなダウンロードフォルダに exe ファイルが転送される

    ![screen3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/3badc324-001f-2fbf-cebd-82a49c1c86cc.png)


- exe ファイルをクリックして実行、インストールを開始する

    ![screen4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/6233e7c6-3cb1-21dd-7128-f0e396065917.png)


- 「NEXT」を押下

    x86_64, win32 を選んで、NEXT。
    ![screen5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/bb4135ab-a868-9598-6b02-2929bad727b1.png)


- 「Program Files」など空白を含んでいると、あとで面倒なことになるらしいので、別のフォルダを指定してインストールを続行

    ![screen6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/004c82b1-7156-237a-d6d7-0621db927cbf.png)


- なぜかインストールに失敗、普通はこのまま問題なく行くんだけどね

    ![screen7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/eca7381c-24a1-10aa-f283-28b9a5610c58.png)

- 失敗した場合は、「7z ファイルをダウンロードして自分で展開しろ」って書いてある

    https://home.hiroshima-u.ac.jp/rgdlab/rgdl_html/programming/gfortran_install2.htm

    インストーラを使わなくても展開するだけでいいらしい。展開したら、C:/ に移動。「C:/Program Files とか、空白文字のあるフォルダは避けたほうが無難」とのこと。



## 1-4, 簡単に動作チェック（ここの項目は飛ばせます）

- コマンドラインから、g++ が動いていることを確認する。

- Path を設定してもいいけど、設定しなくても [VSCode]からビルド＆デバッグできるようになる。

    追記：

    コーディングを進めていくと、exe 実行時に「DLLが見つからない」というエラーが出るようになる。それは exe が実行時に、bin の中にある DLL を参照するからで、bin に Path が通っていないため発生する問題なのだが、Path を通して解決するよりも、exe と同じフォルダに参照する DLL をコピーしてくるか、ビルド時のリンクオプションに -static を指定することで回避できる。どのような exe を作成したいのか？考慮して回避手段を選ぶとよいと思うが、Path を通して解決すると、リリース時に梱包し忘れて「DLLが見つからない」となり、客先であたふたすることが目に見えるので、ここではおすすめしない。

    参考：
    msys2とC++で特定のDLLに依存しないwindowsバイナリを作る
    http://siuncyclone.hatenablog.com/entry/2018/07/21/194629

# 2, [VSCode] のインストール

## 2-1, [VSCode] とは

デバッガ連携機能が充実した高性能なテキストエディタ。全プログラマにおすすめの超パワーツール。いまさら説明するのがアホみたい。

[VSCode]:https://code.visualstudio.com/

## 2-2, インストール

- 次のページからダウンロード

    https://code.visualstudio.com/
    ![vscode1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/9bc2e967-40ea-2a9a-ad50-658c30aa830d.png)


- インストール後の MinGW の設定はここに詳しく書いてある（英語だけど、翻訳すれば理解できる）

    https://code.visualstudio.com/docs/cpp/config-mingw

    同じ内容になるけど、以下で順番に説明します。

## 2-3, 拡張機能 C/C++ をインストール

[VSCode] の拡張機能 C/C++ をインストールする。みんな普通に使っている機能だと思うので、ここでは詳しく説明しないけど、ここで入れておいてほしいのは「C/C++」拡張機能です。

- 日本語パック
- C/C++

    ![vscode2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/05bc18ab-3d5c-f313-9f41-dda00c1112a0.png)

    ちなみに、この状態で、マークダウン形式(.md)のプレビューができる（Ctrl + Shift + V）。[VSCode] のデフォルト機能と思われる（失礼、脱線しました）。


## 2-4, Git のインストール（この項目は飛ばせる）

なにかと便利なので、Git は入れておくとよい。入れなくてもビルド＆デバッグまで行ける。
ただ、結局はバージョン管理もすることになるのだし、[VSCode] は Git 前提で作られているので、便利に使い倒すつもりならインストールすべき。

この辺のページが参考になる。

https://qiita.com/manabu-watanabe/items/ecf1b434baf305adaa00


## 2-5, [VSCode] いろいろ設定

[MinGW] を使って、C++のビルドやデバッグを[VSCode]から行えるようにするには設定がいる。ここが山場。とはいえ、そんなに難しいことが要求されているわけではない。

### ソースコードを置くための空のフォルダーを準備

空のフォルダー（例えば「gcc_test」）を作り、そのフォルダーを [VSCode] で開く。

注意：ここでフォルダ作成に日本語（いわゆる全角文字）が入らないように気をつけてください。また半角空白文字も避けてください。あとで苦労することになります。

この設定が完了すると、.vscodeサブフォルダーに3つのファイルが作成される。

- (1) c_cpp_properties.json （コンパイラパスとIntelliSense設定）
- (2) tasks.json （ビルド手順）
- (3) launch.json （デバッガー設定）

新しくフォルダを作るたびにこの(1)～(3)を繰り返す必要があるが、それはそれで面倒なので、フォルダを作った直後に .vscode もまるっとコピーしちゃうのがいいと思う。もちろん、細かい設定が入っている可能性が高いので、そこは対応が必要だけど。

### (1) g++コンパイラパスの設定

- メニューから View > Command Palette or Ctrl + Shift + P 押して「C/C++」を入力「C/C++ : Edit Configurations (UI)」を選択

    ![vscode3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/75cf12bf-4abc-e623-5c0f-2ff534e9164b.png)


- 「Edit Configurations (UI)」が開き編集できるようになる

    ![vscode4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/d73c3998-4cfa-f543-4a70-c6bd5534eab2.png)


- コンパイラ g++.exe パスを設定

    ![vscode5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/fd58fce8-3174-ffd2-4a27-19963e8097b7.png)


- 「Add Configuration」押す
    ![vscode6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/0a878ee3-910e-dcdc-dc7c-94b30982a6f0.png)

    g++ のパス設定が c_cpp_properties.json に保存される。（なんか、画面キャプチャの途中で日本語環境に切り替わった、アップデート？した模様。）

### (2) ビルド手順の作成

- メニューから View > Command Palette or Ctrl + Shift + P 押して「Tasks」を入力「Tasks: Configure Default Build Task.」を選択

    ![vscode7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/74403245-288d-0f3b-e7d4-0a6c47693e13.png)


- tasks.json が自動生成されるのでそのまま保存

    ![vscode8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/eabc6649-f293-8edc-9149-07f4ff993ac4.png)


    ```js
    {
        // tasks.json 形式の詳細についての資料は、
        // https://go.microsoft.com/fwlink/?LinkId=733558 をご覧ください
        "version": "2.0.0",
        "tasks": [
            {
                "type": "shell",
                "label": "g++.exe build active file",
                "command": "D:/Program_Files_x86/MinGW64/bin/g++.exe",
                "args": [
                    "-g",
                    "${file}",
                    "-o",
                    "${fileDirname}\\${fileBasenameNoExtension}.exe"
                ],
                "options": {
                    "cwd": "D:/Program_Files_x86/MinGW64/bin"
                },
                "problemMatcher": [
                    "$gcc"
                ],
                "group": {
                    "kind": "build",
                    "isDefault": true
                }
            }
        ]
    }
    ```

- ビルドお試しコードを入力

    こんな感じに、かんたんなC++コード test.cpp を作成

    ```cpp
    #include <string>

    int main()
    {
        std::string hello = "Hello C++!";
        puts( hello.c_str() );

        return 0 ;
    }

    ```

- 試しにビルド Ctrl + Shift + B を実行してみる

    ビルドがうまくいくと、ターミナルに、特にエラーもなく、あっけなく終わったことが表示される。

    ![vscode9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/af7e08c6-271b-2c74-7796-4a7060019ad5.png)

    test.cpp の隣に test.exe ファイルも作成されているのが確認できる。


追記：
ここで、test.exe を起動（エクスプローラーからダブルクリック）してみると、「システムエラー dll が見つかりません」というエラーが出ることがある。それは（前にも書いたけど）、DLLファイルのある場所までの PATH が通っていない（環境変数を設定していない）のが原因です。でも、PATH を通して解決するよりも、DLLを使わないスタティックリンクの指定をするか、もしくは必要な DLL を exe と同じ位置に置くことで解決する方法をおすすめします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/19249428-150a-5ebb-7657-a85d33e630d5.png)

ちにみに、今回、 test.exe で必要になったのは以下の３つの  DLL ファイル。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/f905d25b-08cd-f90e-579b-89f7e62704c3.png)


### (3) デバッグ手順の作成

- 「F5」キーを押してデバッグ実行してみると launch.json が無いので、「環境の選択」が現れる。ここで「C++(GDB/LLDB)」を選択する。

    ![debug1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/7f7857b1-82f6-402f-54fe-8916f8ae8d3c.png)


- 右下に表示される「構成の選択」ボタンを押して出てくるメニューの中から、「C/C++:（gdb）起動」を選択。

    ![debug2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/466147aa-0099-fb8b-ef60-9f62a273fef2.png)


- ３箇所( // <- のところ)修正して、再び「F5」を押すと test.exe が gdb.exe 経由で実行される。

    ```js
    {
        // IntelliSense を使用して利用可能な属性を学べます。
        // 既存の属性の説明をホバーして表示します。
        // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
        "version": "0.2.0",
        "configurations": [
            {
                "name": "(gdb) 起動",
                "type": "cppdbg",
                "request": "launch",
                "program": "${workspaceFolder}/test.exe", // <- test.exe
                "args": [],
                "stopAtEntry": false,
                "cwd": "${workspaceFolder}",
                "environment": [],
                "externalConsole": true, // <- true
                "MIMode": "gdb",
                "miDebuggerPath": "D:/Program_Files_x86/MinGW64/bin/gdb.exe", // <- フルパス
                "setupCommands": [
                    {
                        "description": "gdb の再フォーマットを有効にする",
                        "text": "-enable-pretty-printing",
                        "ignoreFailures": true
                    }
                ]
            }
        ]
    }
    ```

    ![debug3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/7aacae53-376c-ea22-84fb-317c2372e7bc.png)



- test.cpp にブレイクポイントを指定してから「F5」を押す

    ![debug4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/29b4f984-613e-04c8-0605-e529bad0945e.png)

    この画面から、プログラムが途中で止まり、デバッグができていることがわかる。

追記：
その後、launch.json に"preLaunchTask"という項目が指定できることを知りました。

```
            "preLaunchTask": "g++.exe build active file"
```

これまで、「F5」キーはデバッグ起動のみで、ビルドは別途「Ctrl + Shift + B」を押す必要があったのですが（正直、「めんどくさっ🥱」と思っていました。😅）、そのめんどくささが解消されて、「F5」キーのみで、ビルドからデバッグまでできるようになりました。いつのまに！！ありがとうございます！！＞MSのみなさま

念の為、動作が確認できている launch.json を貼っておきます。

```JS:launch.json
{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "gcc.exe - build & debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "D:\\Program_Files_x86\\MinGW64\\bin\\gdb.exe",
            "setupCommands": [
                {
                    "description": "gdb の再フォーマットを有効にする",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "g++.exe build active file" // ★重要！
        }
    ]
}
```



おめでとうございます。これで無事にC++のビルドとデバッグができていることが確認できました。あとはよしなに。

# ハマりポイント

うまく動かないひとへ

- フォルダ名に全角文字（日本語文字）があるとうまく行かない。g++.exe / gdb.exe が対応していないのか、[VSCode] がうまく渡せないのか、謎。

追記：どうやら gdb.exe が対応していないっぽい。ビルドはできるが、デバッガで以下のようなメッセージが出る。
`Unable to start debugging. Unexpected GDB output from command ...`
はやく対応されるといいなぁ。回避方法をご存知な方はコメントをくださいませ。よろしくお願いいたします。
![debug5NG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/840c5055-5751-4f5b-e519-510babc51acc.png)


# まとめ

- [VSCode] で [MinGW]-64 のビルドとデバッグは、それほど難しくない。

- しかし、全自動で動くようになるわけではない。ハマリポイント（全角文字）もあるし。確認しながら進めていけば大丈夫。

- 動いてしまえば、どうということはない。

みなさまの快適な C++ ライフを応援しています。

間違いなどのコメントがありましたら、お願いします。