Visual Studio Code での Clang の使用
このチュートリアルでは、macOS で Visual Studio Code を構成して、Clang/LLVM コンパイラとデバッガーを使用する方法について説明します。
VS Code を構成したら、VS Code で C++ プログラムをコンパイルおよびデバッグします。このチュートリアルでは、Clang や C++ 言語については説明しません。これらのトピックについては、Web 上に多くの優れたリソースがあります。
問題が発生した場合は、VS Code ドキュメントリポジトリでこのチュートリアルの問題を自由に提出してください。
前提条件
このチュートリアルを正常に完了するには、次の手順を実行する必要があります。
-
VS Code 用 C++ 拡張機能をインストールします。拡張機能ビュー (⇧⌘X (Windows、Linux Ctrl+Shift+X)) で「C++」を検索して、C/C++ 拡張機能をインストールできます。
Clang がインストールされていることを確認します。
Clang は Mac に既にインストールされている可能性があります。インストールされていることを確認するには、macOS ターミナルウィンドウを開き、次のコマンドを入力します。
clang --version
Clang がインストールされていない場合は、次のコマンドを入力して、Clang を含むコマンドライン開発者ツールをインストールします。
xcode-select --install
Hello World アプリケーションの作成
macOS ターミナルから、VS Code プロジェクトをすべて保存できる projects
という名前の空のフォルダーを作成し、次に helloworld
という名前のサブフォルダーを作成し、そのフォルダーに移動して、ターミナルウィンドウに次のコマンドを入力して、そのフォルダーで VS Code を開きます。
mkdir projects
cd projects
mkdir helloworld
cd helloworld
code .
code .
コマンドは、現在の作業フォルダーで VS Code を開き、それが「ワークスペース」になります。チュートリアルを進めるにつれて、ワークスペースの .vscode
フォルダーに 3 つのファイルが作成されます。
tasks.json
(コンパイラビルド設定)launch.json
(デバッガー設定)c_cpp_properties.json
(コンパイラパスと IntelliSense 設定)
Hello World ソースコードファイルを追加します。
エクスプローラーのタイトルバーで、[新しいファイル] ボタンを選択し、ファイルに helloworld.cpp
という名前を付けます。
次のソースコードを貼り付けます。
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> msg {"Hello", "C++", "World", "from", "VS Code", "and the C++ extension!"};
for (const string& word : msg)
{
cout << word << " ";
}
cout << endl;
}
次に、⌘S (Windows、Linux Ctrl+S) を押してファイルを保存します。ファイルが VS Code のサイドバーにある [エクスプローラー] ビュー (⇧⌘E (Windows、Linux Ctrl+Shift+E)) にリストされていることに注意してください。
[ファイル] > [自動保存] を選択して、自動保存を有効にして、ファイルの変更を自動的に保存することもできます。VS Code のその他のビューの詳細については、ユーザーインターフェースドキュメントを参照してください。
注: C++ ファイルを保存または開くと、C/C++ 拡張機能から、新機能と修正をテストできる Insiders バージョンの可用性に関する通知が表示される場合があります。
X
([通知のクリア]) を選択して、この通知を無視できます。
IntelliSense の探索
IntelliSenseは、コード補完、パラメーター情報、クイック情報、メンバーリストなどのコード編集機能を追加することにより、より速く、より効率的にコーディングするのに役立つツールです。
IntelliSense が動作していることを確認するには、vector
または string
にカーソルを合わせると、型情報が表示されます。10 行目で msg.
と入力すると、IntelliSense によって生成された、呼び出す推奨メンバー関数の補完リストが表示されます。
Tab キーを押して、選択したメンバーを挿入できます。次に、開き括弧を追加すると、関数に必要な引数に関する情報が表示されます。
IntelliSense がまだ構成されていない場合は、コマンドパレット (⇧⌘P (Windows、Linux Ctrl+Shift+P)) を開き、「IntelliSense 構成の選択」と入力します。コンパイラのドロップダウンから、[clang++ を使用する
] を選択して構成します。詳細については、IntelliSense 構成ドキュメントを参照してください。
helloworld.cpp の実行
C++ 拡張機能は、マシンにインストールした C++ コンパイラを使用してプログラムをビルドすることを忘れないでください。VS Code で helloworld.cpp
を実行およびデバッグする前に、Clang などの C++ コンパイラがインストールされていることを確認してください。
-
helloworld.cpp
を開いて、アクティブなファイルにします。 -
エディターの右上隅にある再生ボタンを押します。
-
システムで検出されたコンパイラのリストから [C/C++: clang++ ビルドとアクティブなファイルのデバッグ] を選択します。
コンパイラを選択するように求められるのは、helloworld.cpp
を最初に実行したときだけです。このコンパイラは、tasks.json
ファイルで設定された「デフォルト」コンパイラです。
-
ビルドが成功すると、プログラムの出力が統合された [デバッグコンソール] に表示されます。
おめでとうございます!VS Code で最初の C++ プログラムを実行しました!
tasks.json について
プログラムを最初に実行すると、C++ 拡張機能によって、プロジェクトの .vscode
フォルダーにある tasks.json
が作成されます。tasks.json
にはビルド構成が格納されます。
macOS 上の tasks.json
ファイルのサンプルを次に示します。
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: clang++ build active file",
"command": "/usr/bin/clang++",
"args": [
"-fcolor-diagnostics",
"-fansi-escape-codes",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}
注:
tasks.json
変数の詳細については、変数リファレンスを参照してください。
command
設定は、実行するプログラムを指定します。この場合は clang++
です。
args
配列は、clang++ に渡されるコマンドライン引数を指定します。これらの引数は、コンパイラが想定する順序で指定する必要があります。
このタスクは、C++ コンパイラにアクティブなファイル (${file}
) を取得し、コンパイルして、アクティブなファイルと同じ名前でファイル拡張子のない (${fileBasenameNoExtension}
) 出力ファイル (-o
スイッチ) を現在のディレクトリ (${fileDirname}
) に作成するように指示します。このプロセスにより、helloworld
が作成されます。
label
値は、タスクリストに表示されるものであり、個人の好みに基づいています。
detail
値は、タスクリスト内のタスクの説明です。この文字列を更新して、同様のタスクと区別します。
problemMatcher
値は、コンパイラの出力でエラーと警告を見つけるために使用する出力パーサーを選択します。clang++ の場合、$gcc
問題マッチャーが最良の結果を作成します。
今後は、再生ボタンは常に tasks.json
から読み取り、プログラムのビルド方法と実行方法を把握します。tasks.json
で複数のビルドタスクを定義でき、デフォルトとしてマークされているタスクは再生ボタンで使用されるタスクです。デフォルトのコンパイラを変更する必要がある場合は、コマンドパレットで [タスク: 既定のビルドタスクの構成] を実行できます。または、tasks.json
ファイルを変更し、このセグメントを置き換えることでデフォルトを削除することもできます。
"group": {
"kind": "build",
"isDefault": true
},
これで
"group": "build",
tasks.json の変更
"${file}"
の代わりに "${workspaceFolder}/*.cpp"
のような引数を使用することで、tasks.json
を変更して複数の C++ ファイルをビルドできます。これにより、現在のフォルダー内のすべての .cpp
ファイルがビルドされます。また、"${fileDirname}/${fileBasenameNoExtension}"
をハードコードされたファイル名 (たとえば、"${workspaceFolder}/myProgram.out"
) に置き換えることで、出力ファイル名を変更することもできます。
helloworld.cpp のデバッグ
コードをデバッグするには、
-
helloworld.cpp
に戻って、アクティブなファイルにします。 -
エディターの余白をクリックするか、現在の行で F9 キーを使用してブレークポイントを設定します。
-
再生ボタンの横にあるドロップダウンから [C/C++ ファイルのデバッグ] を選択します。
-
システムで検出されたコンパイラのリストから [C/C++: clang++ ビルドとアクティブなファイルのデバッグ] を選択します (
helloworld.cpp
を最初に実行またはデバッグするときにのみコンパイラを選択するように求められます)。 -
タスクが実行され、出力が [ターミナル] ウィンドウに出力されるのがわかります。
再生ボタンには、[C/C++ ファイルの実行] と [C/C++ ファイルのデバッグ] の 2 つのモードがあります。デフォルトは最後に使用したモードです。再生ボタンにデバッグアイコンが表示されている場合は、ドロップダウンメニュー項目を選択する代わりに、再生ボタンを選択してデバッグできます。
デバッガーの探索
コードのステップ実行を開始する前に、ユーザーインターフェースのいくつかの変更点に注目してください。
-
ソースコードエディターの下部に統合ターミナルが表示されます。[デバッグコンソール] タブに、デバッガーが起動して実行されていることを示す出力が表示されます。
-
エディターは、デバッガーを開始する前にブレークポイントを設定した行を強調表示します。
-
アクティビティバーの [実行とデバッグ] ビューにデバッグ情報が表示されます。
-
コードエディターの上部に、デバッグコントロールパネルが表示されます。左側のドットを掴むことで、これを画面上で移動できます。
コードのステップ実行
これで、コードのステップ実行を開始する準備が整いました。
-
デバッグコントロールパネルの [ステップオーバー] アイコンを選択して、
for (const string& word : msg)
ステートメントが強調表示されるようにします。[ステップオーバー] コマンドは、
msg
変数が作成および初期化されるときに呼び出されるvector
およびstring
クラス内のすべての内部関数呼び出しをスキップします。[変数] ウィンドウの変更に注意してください。msg
の内容は、そのステートメントが完了したため、表示されています。 -
[ステップオーバー] をもう一度押して、次のステートメントに進みます (ループを初期化するために実行されるすべての内部コードをスキップします)。これで、[変数] ウィンドウにループ変数に関する情報が表示されます。
-
[ステップオーバー] をもう一度押して、
cout
ステートメントを実行します。 -
必要に応じて、ベクター内のすべての単語がコンソールに出力されるまで [ステップオーバー] を押し続けることができます。しかし、興味がある場合は、[ステップイン] ボタンを押して、C++ 標準ライブラリのソースコードをステップ実行してみてください!
ウォッチの設定
プログラムの実行中に変数の値を追跡したい場合があります。変数の ウォッチ を設定することで、これを行うことができます。
-
[ウォッチ] ウィンドウで、プラス記号を選択し、テキストボックスに
word
と入力します。これは、ループ変数の名前です。ループをステップ実行するときに、[ウォッチ] ウィンドウを表示します。注: ウォッチ変数の値は、プログラムの実行が変数のスコープ内にある場合にのみ使用できます。たとえば、ループ変数の場合、値はプログラムがループを実行している場合にのみ使用できます。
-
ループの前に次のステートメントを追加して、別のウォッチを追加します。
int i = 0;
。次に、ループ内で、次のステートメントを追加します。++i;
。前の手順で行ったように、i
のウォッチを追加します。 -
実行が一時停止している間にマウスカーソルを任意の変数に合わせると、その値をすばやく表示できます。
launch.json を使用したデバッグのカスタマイズ
再生ボタンまたは F5 でデバッグすると、C++ 拡張機能は動的なデバッグ構成をその場で作成します。
実行時にプログラムに渡す引数を指定するなど、デバッグ構成をカスタマイズしたい場合があります。launch.json
ファイルでカスタムデバッグ構成を定義できます。
launch.json
を作成するには、再生ボタンのドロップダウンメニューから [デバッグ構成の追加] を選択します。
次に、さまざまな事前定義されたデバッグ構成のドロップダウンが表示されます。[C/C++: clang++ ビルドとアクティブなファイルのデバッグ] を選択します。
VS Code は、次のような launch.json
ファイルを作成します。
{
"configurations": [
{
"name": "C/C++: clang++ build and debug active file",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"preLaunchTask": "C/C++: clang++ build active file"
}
],
"version": "2.0.0"
}
program
設定は、デバッグするプログラムを指定します。ここでは、アクティブなファイルフォルダー ${fileDirname}
とアクティブなファイル名 ${fileBasenameNoExtension}
に設定されており、helloworld.cpp
がアクティブなファイルの場合、helloworld
になります。args
プロパティは、実行時にプログラムに渡す引数の配列です。
デフォルトでは、C++ 拡張機能はソースコードにブレークポイントを追加せず、stopAtEntry
値は false
に設定されています。
stopAtEntry
値を true
に変更して、デバッグを開始するとデバッガーが main
メソッドで停止するようにします。
preLaunchTask
値が tasks.json
ファイルのビルドタスクの label
と一致していることを確認してください。
今後は、再生ボタンと F5 は、プログラムをデバッグするために起動するときに
launch.json
ファイルから読み取ります。
C/C++ 設定の追加
C/C++ 拡張機能をより詳細に制御するには、c_cpp_properties.json
ファイルを作成します。これにより、コンパイラへのパス、インクルードパス、コンパイル対象の C++ 標準 (C++17 など) などの設定を変更できます。
コマンドパレット (⇧⌘P (Windows、Linux Ctrl+Shift+P)) からコマンド [C/C++: 構成の編集 (UI)] を実行して、C/C++ 構成 UI を表示します。
これにより、[C/C++ 構成] ページが開きます。
Visual Studio Code は、これらの設定を .vscode/c_cpp_properties.json
に配置します。そのファイルを直接開くと、次のようになります。
{
"configurations": [
{
"name": "Mac",
"includePath": ["${workspaceFolder}/**"],
"defines": [],
"macFrameworkPath": [
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "macos-clang-arm64"
}
],
"version": 4
}
プログラムにワークスペースまたは標準ライブラリパスにないヘッダーファイルが含まれている場合にのみ、[インクルードパス] 設定を変更する必要があります。
コンパイラパス
拡張機能は、compilerPath
設定を使用して、C++ 標準ライブラリヘッダーファイルへのパスを推測します。拡張機能がこれらのファイルの場所を認識すると、スマート補完や [定義へ移動] ナビゲーションなどの機能を提供できます。
C/C++ 拡張機能は、システムで見つかったものに基づいて、デフォルトのコンパイラの場所で compilerPath
を設定しようとします。compilerPath
検索順序は次のとおりです。
- 既知のコンパイラの名前の PATH。リストにコンパイラが表示される順序は、PATH によって異なります。
- 次に、
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/
などのハードコードされた Xcode パスが検索されます。
詳細については、IntelliSense 構成ドキュメントを参照してください。
Mac フレームワークパス
[C/C++ 構成] 画面で、下にスクロールして [詳細設定] を展開し、[Mac フレームワークパス] がシステムヘッダーファイルを指していることを確認します。例: /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks
トラブルシューティング
コンパイラとリンカーのエラー
エラーの最も一般的な原因 (undefined _main
、または attempting to link with file built for unknown-unsupported file format
など) は、ビルドを開始またはデバッグを開始するときに helloworld.cpp
がアクティブなファイルでない場合に発生します。これは、コンパイラがソースコードではないもの (launch.json
、tasks.json
、または c_cpp_properties.json
ファイルなど) をコンパイルしようとしているためです。
"C++11 extensions" に言及するビルドエラーが表示される場合は、tasks.json
ビルドタスクを更新して、clang++ 引数 --std=c++17
を使用していない可能性があります。デフォルトでは、clang++ は C++98 標準を使用しますが、これは helloworld.cpp
で使用されている初期化をサポートしていません。helloworld.cpp の実行 セクションで提供されているコードブロックで tasks.json
ファイルの内容全体を置き換えるようにしてください。
ターミナルが入力用に起動しない
macOS Catalina 以降では、"externalConsole": true
を設定した後でも、入力を入力できない問題が発生する可能性があります。ターミナルウィンドウは開きますが、実際には入力を入力することはできません。
この問題は現在 #5079 で追跡されています。
回避策は、VS Code にターミナルを一度起動させることです。これを行うには、tasks.json
に次のタスクを追加して実行します。
{
"label": "Open Terminal",
"type": "shell",
"command": "osascript -e 'tell application \"Terminal\"\ndo script \"echo hello\"\nend tell'",
"problemMatcher": []
}
[ターミナル] > [タスクの実行...] を使用してこの特定のタスクを実行し、[ターミナルを開く] を選択できます。
アクセス許可要求を受け入れると、デバッグ時に外部コンソールが表示されます。
次のステップ
- VS Code ユーザーガイドを参照してください。
- C++ 拡張機能の概要を確認してください。
- 新しいワークスペースを作成し、.json ファイルをコピーして、新しいワークスペースパス、プログラム名などに必要な設定を調整し、コーディングを開始してください!