WSL(Ubuntu) C++開発環境をVS Codeで構築
2018年3月、Windows Subsystem for Linux(WSL)で動作するUbuntuのC++開発環境をWindows環境で動作するVisual Studio Codeで実現しました。
マイクロソフトが WSLを正式リリースして、Microsoft StoreからUbuntuがダウンロードできるようになり、WindowsでLinuxが動作するという便利な時代となりました。
Visual Studio Code(VS Code)を使用して、Windows Subsystem for Linuxで動作するUbuntuのC++開発環境を構築しました。VS Codeは、マイクロソフト社が開発したクロスプラットフォームで動作する高機能なソースコードエディターです。VS Codeはエディターであり、Visual Studio 20xx のような統合開発環境(IDE)ではありません。しかし、デバッグ機能やタスク機能(頻繁に行う作業の自動化)が組み込まれています。従って、「コード編集→ビルド処理→デバッグ実行」がVS Code内で行うことができます。
Ubuntu C++開発環境
最初に Windows Subsystem for Linux (Ubuntu) のC++開発環境を構築します。
gccを使用できるように開発ツールをインストールします。
sudo apt install build-essential
gdbデバッガをインストールします。
sudo apt install gdb
使用したツールのバージョンを下記に示します。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.4 LTS Release: 16.04 Codename: xenial
$ gcc --version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 Copyright (C) 2015 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.
$ gdb --version GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu".
$ make --version GNU Make 4.1 Built for x86_64-pc-linux-gnu Copyright (C) 1988-2014 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
C++ 作業ディレクトリー
C++言語をビルドして実行するのは、WSLで動作する Ubuntu環境です。また、Visual Studio Codeは、Windows環境で動作します。
今回は、このUbuntu環境とWindows環境を連携したC++開発環境を構築します。Windows環境からUbuntu環境のファイルへの(追加/変更/削除)アクセスは禁止されていますので、作業ディレクトリーをWindows側にします。
「c:\Users\pi\MyHome」をWindows環境とUbuntu環境から共通でアクセスする作業ディレクトリーとします。
MyHome ディレクトリーを作成します。
$ pwd /home/pi $ cd /mnt/c/Users/pi $ sudo mkdir MyHome $ cd MyHome
.bashrc の最後に、カレントディレクトリーを MyHome にするコマンドを入れます。
$ cd $ pwd /home/pi $ tail -1 .bashrc cd /mnt/c/Users/pi/MyHome
次にログインすると、/mnt/c/Users/pi/MyHome がカレントディレクトリーになります。
Visual Studio Codeのインストール
マイクロソフトのVisual Studio CodeサイトからVisual Studio Codeをダウンロードします。
「Visual Studio Code ダウンロード」を入力します。
Windowsプラットフォームを選択します。
インストールを開始します。
Visual Studio Code を実行します。
「Gitが見つかりません」とメッセージが表示されます。Gitは使いませんので、 [今後は表示しない]をクリックします。
Visual Studio Code のバージョンを確認します。
「ヘルプ(H)-バージョン情報(A)」と入力します。
バージョン 1.21.1 コミット 79b44aa704ce542d8ca4a3cc44cfca566e7720f1 日付 2018-03-14T14:46:47.128Z シェル 1.7.9 レンダラー 58.0.3029.110 Node 7.9.0 アーキテクチャ x64
統合ターミナルの設定
Visual Studio Code の統合ターミナルで、WSL(Ubuntu)のbashを使うように設定します。
「[Ctrl]+[Shift]+[P]キー」でコマンドパレットを表示して「shell」と入力します。
「ターミナル:規定のシェルの選択」を入力します。
シェルの選択項目が表示されます。
- Command Prompt
- PowerShell
- WSL Bash
「WSL Bash c:\WINDOWS\System32\bash.exe」を選択します。
「表示(V)-統合ターミナル(I)」または、[Ctrl]+[Shift]+[@]キーを入力します。
画面下にUbuntu環境のbashターミナルが開きます。
C++言語のサンプルコード
これからVisual Studio Code でC++言語の開発環境を構築します。文字のASCIIコードを表示する簡単なC++言語のサンプルコードを使用します。
MyHomeに cpp_outAscii ディレクトリーを作成して、ソースコード outAsciiCode.cpp を作成します。
「[ファイル(F)]-[フォルダを開く]」で、c:\Users\pi\MyHome\cpp_outAscii を指定します。次に「[ファイル(F)]-[新規ファイル(N)]」で、outAsciiCode.cppを指定します。
#include <stdio.h> char cvhex(int ihex) { char cHex; if (ihex <10) { cHex = '0' + ihex; } else { cHex = 'A' + ihex - 10; } return(cHex); } void outAsciiCode(char code) { int ih = int(code / 16); int il = int(code % 16); char ch = cvhex(ih); char cl = cvhex(il); printf("%c \t %c%c \n", code ,ch,cl); } int main(void) { outAsciiCode('1'); outAsciiCode('A'); outAsciiCode('I'); outAsciiCode('J'); outAsciiCode('a'); }
ソースコードをWindows環境とUbuntu環境からアクセスすることを考慮して、文字コードのエンコードを BOM付き Unicode(UTF-8)にします。
右下の 「UTF-8」をクリックします。
[エンコード付きで保存]を選択します。
[UTF-8 with BOM]を選択します。
Ubuntu環境でのビルドと実行
次に makefile を作成します。
# Makefile # # make clean # make # make exec # #----------------------------------------- ##### TARGET = outAscii OBJ = OBJ += outAsciiCode.o # Optimaze Option # CFLAGOPT = CFLAGOPT += -O0 # # # cc options: CFLAGS = CFLAGS += -Wall CFLAGS += -g CFLAGS += $(CFLAGOPT) # # Link-time cc options: LDFLAGS = CC = gcc CPP = g++ #----------------------------- Command # file deletion command RM= rm -f # linker LN= $(CC) #---------------------------------------------- all: $(TARGET) .c.o: #----------------------------------------------------- [$<] $(CC) $(CFLAGS) -c $*.c .cpp.o: #----------------------------------------------------- [$<] $(CPP) $(CFLAGS) -c $*.cpp $(TARGET) : $(OBJ) #------------------------------------------------------ LINK $(LN) -o $(TARGET) $(OBJ) $(LDFLAGS) clean: $(RM) *.o $(TARGET) exec: ./$(TARGET)
gdbでデバッグしますので、次のオプションを付けます。
- -g : コンパイル,リンク時にDEBUG情報を付加する
- -O0 : 最適化をしません
「表示(V)-統合ターミナル(I)」 で、ターミナルを開きます。
makeコマンドでビルドします。
$make #----------------------------------------------------- [outAsciiCode.cpp] g++ -Wall -g -O0 -c outAsciiCode.cpp #------------------------------------------------------ LINK gcc -o outAscii outAsciiCode.o
outAscii を実行して、結果を確認します。
$ ./outAscii 1 31 A 41 I 49 J 4A a 61
makefileに実行用のオプションを入れましたので、makeコマンドからでも実行できます。
$ make exec ./outAscii 1 31 A 41 I 49 J 4A a 61
Visual Studio Codeからビルド
Visual Studio Code から、プログラムのビルドをできるようにします。
「タスク(T)-ビルドタスクの実行(B)」と入力します。
「ビルドタスクを構成する…」をクリックします。
「テンプレートから task.json を生成」をクリックします。
「Others 任意の外部コマンドを実行する例」を選択します。
task.json のひな形が表示されます。
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "echo", "type": "shell", "command": "echo Hello" } ] }
task.json を下記のように修正して、makeコマンドを実行するようにします。
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "My build", "type": "shell", "command": "make", "group": { "kind": "build", "isDefault": true } } ] }
項目の意味は、Tasks in Visual Code ドキュメントを参考にします。
項目 | 設定例 | 意味 |
---|---|---|
label | My build | ユーザーインターフェイスで使用するタスクのラベル |
type | shell | タスクのタイプ (shell or process) ・shell : コマンドはシェルコマンドとして解釈 ・process : コマンドは実行するプロセスとして解釈 |
command | make | 実行する実際のコマンド |
group | build | 実行タスクが属するグループ (build or test) |
「タスク(T)-ビルドタスクの実行(B)」 または、[Ctrl]+[Shift]+[B]キーで、makeコマンドを実行してビルドします。
Visual Studio Codeからプログラムの実行
Visual Studio Code から、プログラムの実行ができるようにします。
task.json を下記のように修正して、testグループを追加します。
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "My build", "type": "shell", "command": "make", "group": { "kind": "build", "isDefault": true } }, { "label": "My exec", "type": "shell", "command": "make exec", "group": "test" } ] }
「タスク(T)-タスクの実行(R)」と入力します。
タスクの選択になりますので、「My exec」を選択します。
make execコマンドにより、./outAscii プログラムを実行しました。
Visual Studio Code C++拡張機能インストール
左の拡張機能をクリックします。
C/C++を選択してインストールします。
[インストール]をクリックします。
[再読み込み]をクリックします。
C/C++ InteliSense を選択してインストールします。
[インストール]をクリックします。
[再読み込み]をクリックします。
インストール済みの拡張機能を確認します。
Visual Studio Codeからデバッグの設定
Visual Studio Codeからブレークポイントを設定してデバッグできるようにします。
BashOnWindowsでのVisualStudioCodeのlaunch.jsonの書き方を参考にしました。
「デバッグ(D)-デバッグの開始(S)」と入力します。
環境の選択で [More…]を選択します。
launch.json のひな形が表示されます。
{ // IntelliSense を使用して利用可能な属性を学べます。 // 既存の属性の説明をホバーして表示します。 // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "enter program name, for example ${workspaceFolder}/a.exe", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": true, "MIMode": "gdb", "miDebuggerPath": "/path/to/gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] }
右下の「構成の追加…」をクリックします
「C/C++: (gdb) Bash on Windows Launch」を選択します。
元の launch.json ひな形を削除して、以下のようになります。
{ // IntelliSense を使用して利用可能な属性を学べます。 // 既存の属性の説明をホバーして表示します。 // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "(gdb) Bash on Windows Launch", "type": "cppdbg", "request": "launch", "program": "enter program name, for example ${workspaceFolder}/a.exe", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": true, "pipeTransport": { "debuggerPath": "/usr/bin/gdb", "pipeProgram": "C:\\Windows\\sysnative\\bash.exe", "pipeArgs": [], "pipeCwd": "" }, "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] }
launch.json を自分の環境に合わせて修正します。
項目 | 意味 |
---|---|
name | 構成の名前 |
program | Ubuntu環境の実行ファイルのパス |
args | 実行時の引数 |
stopAtEntry | エントリーポイントで停止 |
cwd | Ubuntu環境の実行ディレクトリー |
pipeTransport: debuggerPath |
Ubuntu環境のgdbのパス |
pipeTransport: pipeProgram |
Windows環境のbashのパス |
pipeTransport: pipeArgs |
pipeのオプション |
sourceFileMap | Ubuntu環境とWindows環境のマップ |
以下のようになりました。
{ // IntelliSense を使用して利用可能な属性を学べます。 // 既存の属性の説明をホバーして表示します。 // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "(gdb) Bash on Windows Launch", "type": "cppdbg", "request": "launch", "program": "/mnt/c/Users/pi/MyHome/cpp_outAscii/outAscii", "args": [], "stopAtEntry": false, "cwd": "/mnt/c/Users/pi/MyHome/cpp_outAscii", "environment": [], "externalConsole": true, "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 } ], "sourceFileMap": { "/mnt/c/Users/pi/MyHome/": "C:\\Users\\pi\\MyHome" } } ] }
C/C++: (gdb) Bash on Windows Launchの修正前後の差分を示します。
Visual Studio Codeからデバッグの実行
左のデバッグボタンを押します。
ソースコードの行番号の左をクリックしてブレークポイントを設定します。
「デバッグ(D)-デバッグの開始(S)」と入力します。
ブレークポイントで実行が停止します。左の領域には、変数の内容が表示されます。
「デバッグ(D)-ステップインする(I)」または、F11を入力します。ステップ実行もできました。
まとめ
Windows Subsystem for Linux(WSL)で動作するUbuntuのC++開発環境をVisual Studio Codeで実現することができました。Visual Studio Codeは高機能なエディターですが、Visual Studio 20xx のような統合開発環境(IDE)風に使えます。
今までは、Windows環境はVisual Studio 20xx統合環境で快適に開発できますが、Linux環境はgdbでデバッグが大変という認識を持っていました。しかし、Visual Studio CodeによりUbuntu環境のC++開発が快適にデバッグできる時代になり感激しています。