Visual Studio Code で C++ 開発 with Windows Subsystem for Linux (OS は Windows 10 ですよ)

最近にわかに Visual Studio Code (VSCode) のお勉強をしています。

以前の記事 WSL を使って Windows 10 の上で Linux を動かす - ある日録Windows Subsystem for Linux (WSL)と、その上に Ubuntu を入れたので、VSCode と WSL を使ってC++のビルドとかデバッガとか IntelliSense とか使ってみる。そのための設定。

以下超ざっくり。

VSCode インストール

まあ、これはググればすぐ出来ます。

統合ターミナルを WSL にする

Ctrl-Shift-P Select Default Shell で WSL を選ぶ。

↓に細かい話あり。

Integrated Terminal in Visual Studio Code

とりあえずこれで、Ctrl+@ で統合ターミナルを表示しておけば、VSCode だけで、編集してコンパイルはできる。

g++ -g -Wall source.cpp -o source

とかターミナルでコマンドを打てばよい。

C/C++ extension のインストール

でもまあ、せっかくやるなら、IntelliSenseも使いたいし、デバッガでステップ実行もしたいので、その辺の機能が入った extension を入れる。

左の列の機能拡張ボタンを押すか Ctrl+Shift+X で extension のリストを表示。小窓に c/c++ と入力して検索する。 インストールして、再読み込みすればOK。

C++ programming with Visual Studio Code

ひととおり読んだ方がいいかもしれないが、あまり読んでない。

システムヘッダへのPATH を intelliSense に教えてあげる。

  • c_cpp_properties.json に WSL コンフィグレーションを追加

下記サイトの記述を参考に書く。

vscode-cpptools/Windows Subsystem for Linux.md at master · Microsoft/vscode-cpptools · GitHub

リンク先ではディストリビューションUbuntu 前提で書かれている。WSL上に他のディストリビューションを入れている場合は変更が必要。(そのことも書いてある)。

あと、最後に、一言、WindowsからWSLのファイル書き換えたら酷いことになるよ。的な記載へのリンクがあった気がする。UbuntuとかのファイルがWindowsからたどれるからといって、くれぐれも書き換えないようにしよう。

  • Ctrl+Shift+P c_cpp_configration.json と打ち込み、c_cpp_configuration.json を開く。
  • 以下の WSL (Ubuntuの場合) の Configuration を c_cpp_configuration.json に書く。

          {
              "name": "WSL",
              "intelliSenseMode": "clang-x64",
              "includePath": [
                  "${workspaceRoot}",
                  "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
                  "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
                  "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5/backward",
                  "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
                  "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
                  "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
                  "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
                  "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include"
              ],
              "defines": [
                  "__linux__",
                  "__x86_64__"
              ],
              "browse": {
                  "path": [
                      "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/c++/5",
                      "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu/c++/5",
                      "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include",
                      "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/local/include",
                      "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed",
                      "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/x86_64-linux-gnu",
                      "${localappdata}/Packages/CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc/LocalState/rootfs/usr/include/*"
                  ],
                  "limitSymbolsToIncludedHeaders": true,
                  "databaseFilename": ""
              },
              "cStandard": "c11",
              "cppStandard": "c++17"
          },
    
  • コマンドパレット> c/cpp select configuration で WSL を選ぶ

  • VSCode を再起動すると選択しなおす必要がある件は調査必要
    → と思ったが、c_cpp_properties.json の一番上に書いたらうごいた。Win32 より前にあればいいのか? WSLのコンフィグレーションを Win32 のコンフィグレーションの下に書いてしまうと、次回 VSCode の起動時に Win32 のほうが有効になってしまう。 Select Configuration で選択しているのに。。。そのうち直るかな。

コンパイル

tasks.json を書く。けっこう簡単。

  • tasks.json は Ctrl+Shift+P Configure task とかして、タスクを選ぶと開ける。
  • メニュー>タスク>タスクの構成 でも同じ。

              {
                  "label": "build",
                  "type": "shell",
                  "command": "g++ -g -Wall -O0 VSCodeTest.cpp",
                  "problemMatcher": [
                      "$gcc"
                  ],
                  "group": {
                      "kind": "build",
                      "isDefault": true
                  }
              }
    
  • g++ に -O0 を付けているのは最適化をオフしておかないとデバッグでステップ実行すると変な動きになるため。VisualStudio でやるみたいに DebugビルドとReleaseビルドを分けておいてもいいかもね。

  • isDefault を true にしておくと Ctrl+Shift+B でビルドできる。

実行

tasks.json を書く。これも同じく簡単。

            {
                "label": "run",
                "type": "shell",
                "command": "./a.out",
                "problemMatcher": []
            }

これでメニュー>タスクの実行>run を選ぶと Ubuntubash 上で a.out が実行される。

デバッガ

下記サイトを 参考に launch.json を書く。

https://github.com/Microsoft/vscode-cpptools/blob/master/Documentation/Debugger/gdb/Windows%20Subsystem%20for%20Linux.md

  • Ctrl+Shift+P open launch.json と打ち、launch.json を開く。(lanunch.json がないときどうなるだろう?)
  • launch.json を開くと右に 構成の追加 ボタンがあるので、これを押す。
  • C/C++: (gdb) Bash on Windows Launch を選ぶ
  • テンプレがインサートされるので、必要なとこだけ変更。たしか・・・
    • program
    • cwd
    • sourceFileMap
  • くらいだったような。

          {
              "name": "(gdb) Bash on Windows Launch",
              "type": "cppdbg",
              "request": "launch",
              "program": "/mnt/c/Code/VSCodeTest/a.out",
              "args": [],
              "stopAtEntry": false,
              "cwd": "/mnt/c/Code/VSCodeTest",
              "environment": [],
              "externalConsole": true,
              "sourceFileMap": {
                  "/mnt/c": "c:\\"
              },
              "pipeTransport": {
                  "debuggerPath": "/usr/bin/gdb",
                  "pipeProgram": "C:\\Windows\\sysnative\\bash.exe",
                  "pipeArgs": ["-c"],
                  "pipeCwd": ""
              },
              "setupCommands": [
                  {
                      "description": "Enable pretty-printing for gdb",
                      "text": "-enable-pretty-printing",
                      "ignoreFailures": true
                  }
              ]
          }
    
  • 左のデバッグアイコンを押してデバック用のペインを開いて、さっき作った構成を選択し右三角をぽちっとすれば実行可能。

  • ソースコードの行番号の左をクリックしてブレークポイントをはっておけばそこで止まる。
  • F10 でステップオーバー
  • F11 でステップイン

以上。