2025/02/16更新
2022年4月に作成した記事を、Windows 11 + Ubuntu 24.04 LTSの環境を念頭に更新しました。
以前にWSL2を使ってWindows 11上にUbuntu 24.04 LTSを導入したことを紹介しました。
今回はこの環境とVisual Studio Code (VS Code)を使って、C言語の開発を行えるようにしたいと思います。
Visual Studio Code (VS Code)
Visual Studio Code(VS Code)はMicrosoftが開発するエディターです。
特徴はいろいろあるのですが、拡張機能による高い柔軟性と、クロスプラットフォームであることが挙げられると思います。
VS Codeがサポートしているプログラミング言語はC、C++、Python、Javaなど非常に多くあります。
実際にコンパイルや実行を行うためには、VS Code以外にそれぞれの言語の環境の導入が必要です。
現在ではもっとも人気の開発者環境ツールの1つかもしれません。
構築したい環境
WSL2を利用してWindows上でLinuxを利用できるようにした目的の1つは、Linuxの豊富なプログラミング環境(コンパイラ・デバッガー・インタープリターなど)を利用できるようにするためです。
Windowsでもプログラミング環境をそろえることはできると思います。
しかし、Windows向けのプログラムを作成するのでなければ、Linuxの方が便利ではないかと思います。
したがって、C言語のコンパイラはWSL2のLinux上のものを利用します。
一方、プログラムを作成する環境であるVS CodeはWindows上のものを利用します。VS CodeはクロスプラットフォームなのでLinux版もありますが、日本語入力などを考えるとWindowsの方が優れているためWindows版を利用します。
つまり、Windows上のVS Codeでプログラムを入力しつつ、WSL2のLinuxでコンパイル・実行・デバッグ(リモート開発)を行うというのが、構築したい環境になります。
VS Codeの導入と日本語化
まずはWindowsにVS Codeをインストールしていきましょう。
インストール
インストーラーは下記から取得できます。

インストーラーには実行したユーザーアカウントのみがVS Codeを利用できる「User Installer」と、アカウントを持っている人のすべてがVS Codeを利用することができる「System Installer」の2つがあります。
どちらを選んでも問題ありません。
インストーラーをダウンロードしたら実行してVS Codeをインストールします。
インストーラーは日本語化されていますし、それほど難しくないと思います。オススメとしては途中で表示される「PATHへの追加」を有効にしておくことです(デフォルトで有効になっています)。
なお、PATHへの追加は再起動後に有効になるので、インストールが完了したら一度Windowsを再起動しておきましょう。
日本語化
次にVS Codeを実行してみます。
最初は表示されているメッセージがすべて英語ですが、右下に日本語の言語パックをインストールするメッセージが表示されるはずです。
この「インストールして再起動」を選択しましょう。
VS Codeが再起動され、表示されているメニュー・メッセージが日本語になっているはずです。
日本語化は「Japanese Language Pack for Visual Studio Code」という拡張機能により実現されています。
もし初回起動時に言語パックを入れ損ねた場合は画面左の拡張機能アイコンから導入できます。
拡張機能アイコンを選択すると、拡張機能を検索するためのテキストボックスが表示されるので「Japanese」と入力します。
表示された拡張機能の中から制作者が「Microsoft」と書かれているものを探し、小さい「Install」のボタンを選択します。
これで次のような画面になるので右下の「Restart」を選択します。
これで日本語化されるはずです。
C言語開発のための環境構築
VS Codeが使えるようになったらWSL2上でC言語を開発するための環境を整備します。
WSL2のLinuxへ開発環境の導入
WSL2にコンパイラなどの開発環境が入っていなければ何もできませんので導入しておきましょう。
Ubuntuの場合はbuild-essentialパッケージでコンパイラ等がインストールされます。デバッガー(gdb)も入れておきます。
sudo apt-get update
sudo apt-get install build-essential gdb
ちゃんとインストールできたかどうかはバージョンを表示させて確認しましょう。
$ gcc --version
gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
Copyright (C) 2023 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 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git
Copyright (C) 2024 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
またVS CodeとWSLを連携する際に、データの取得を行うことがあるのでwgetコマンドとca-certificatesをインストールしておきます。
sudo apt-get install wget ca-certificates
VS Codeへ拡張機能の導入
次にVS Codeに必要な拡張機能を導入します。
入れておく必要がある拡張機能は
です。
まず、C言語の開発を補助する「C/C++」と「C/C++ Extension Pack」を導入します。
VS Code画面の左側で拡張機能アイコンを選び「C++」で検索すると、Microsoftが作成した拡張機能である「C/C++」と「C/C++ Extension Pack」が上位に来るはずです。
これらをインストールしておきます。
同様に「Remote Development」で検索して「Remote Development」をインストールします。
「WSL」については「Remote Development」をインストールすることで自動的に導入されると思います。もしインストールされていない場合は、これまでと同様の手順でインストールしておきましょう。
VS Codeを使ったリモート開発
環境が整ったのでさっそく始めてみましょう。
VS CodeとWSL2の接続
まず、VS CodeがWSL2と接続された状態にします。
左下の歯車アイコンを選択して「コマンドパレット」を選びます。
これで画面上部にコマンドを入力するエリアが表示されるので「WSL」と入力すると、「WSL」拡張機能の提供する機能が表示されます。
デフォルトのLinuxディストリビューションを利用する場合は「WSL: WSLへの接続」を選択します。
デフォルト以外のLinuxディストリビューションを使いたい場合は「WSL: ディストリビューションを利用してWSLに接続」を選択して、その後に利用するLinuxディストリビューションを選択します。
これでVS Codeの右下に「WSL: ディストリビューション名」と表示されれば、VS CodeとWSL2が連携できている状態となります。
なお、初回はWSL2側にファイルを導入する必要があるので、少々待ち時間が必要です。
VS CodeとWSL2を連携させる方法はほかにもあります。
左端のリモートエクスプローラアイコンを選択し、「WSLターゲット」になっていることを確認して、使用したいLinuxディストリビューションを選ぶ(右クリックして「現在のウィンドウで接続する」を選択)方法でも同じように連携ができます。
WSL2のLinux側に拡張機能を入れる
VS CodeとWSL2の連携がとれたら、WSL2側に拡張機能を入れていきます。
WSL2のLinuxと連携している状態で、右側の拡張機能を選びます。
そして「LOCAL – インストール済」のところを確認すると「WSL:Ubuntuにインストールする」となっている拡張機能があると思います(「Ubuntu」のところはお使いのディストリビューション名になります)。
このような拡張機能を探し片っ端から「WSL:Ubuntuにインストールする」を選択していきましょう。
プログラムを作成する(コーディング)
使い勝手を確認するために、ここではWSL2のLinuxのホームディレクトリに「vscode/c_test」というディレクトリを作成し、その中にフィボナッチ数を計算するプログラムfibonacci.cを作成することにしましょう。
フォルダーを作成するにはVS Codeで行うこともできますが、ここではVS Codeのターミナルでコマンドを入力します。
まずVS Codeで「ターミナル」→「新しいターミナル」を選択します。すると画面下部にターミナルが表示されWSL2のLinuxのコマンドが入力できるようになります。
ここで次のコマンドを入力してフォルダーを作成します。
mkdir -p vscode/c_test
フォルダーができたら、VS Codeの「ファイル」→「フォルダーを開く」を選択します。
これで画面中央上部に「フォルダーを開く」と表示され、開くフォルダーを選べる状態になります。
VS CodeとWSL2が連携できていれば、ここで選択できるフォルダーはWSL2のLinux内のフォルダーになります。
デフォルトではホームディレクトリが表示されると思うので、先ほど作成したフォルダー(vscode/c_test)を入力してOKを選択します。
すると次のように「フォルダー内のファイルの作成者を信頼しますか?」と聞かれるので、「はい、作成者を信頼します」を選択します。
これでVS Codeの左側の「エクスプローラー」の領域にWSL2のc_testディレクトリが表示されます。
ここで「エクスプローラー」の領域の「C_TEST」部分にマウスを持って行くと「新しいファイル」というアイコンがあるのでこれを選択します。
これでファイルを作成できますので、ファイル名に「fibonacci.c」を入力します。
これでc_testディレクトリの下にファイルfibonacci.cが作成されます。そして、作成されたfibonacci.cが右側に開かれ編集可能な状態となっています。
あとはfibonacci.cに下記のコードを入力します。これは10のフィボナッチ数を計算するコードです。
#include <stdio.h>
static int fibonacci(int n) {
if ( (n== 0) || (n == 1) ) {
return n;
}
return fibonacci(n - 2) + fibonacci(n - 1);
}
int main(int argc, char* argv[]) {
int n = 10;
int fibo;
fibo = fibonacci(n);
printf("fibonacci(%d) = %d\n", n, fibo);
return 0;
}
VS Codeの画面ではこんな感じに色分けされて、見やすくなっているはずです。
実行する
プログラムを作成したら実行してみましょう。
実行はVS Codeのメニューで「実行」→「デバッグ無しで実行」を選択します。Ctrl+F5でもOKです。
するとVS Codeの画面中央上部に「構成の選択」が表示されるので「C/C++:gccアクティブファイルのビルドとでバッグ」を選択します。
「構成の選択」の前に「環境の選択」が表示された場合は、「C++ (GDB)」を選択してください。
これで入力したプログラムがコンパイルされ、実行されます。
ここでは10のフィボナッチ数が55と計算されています。
実行結果が表示されない場合は「ターミナル」を選択してみてください。
デバッグする
せっかくなのでデバッグしてみましょう。
今回は関数fibonacciにブレークポイントを設定して動きを見てみます。
ブレークポイントを設定するにはブレークポイントを設定したい行の行番号の左側をクリックします。
ブレークポイントの設定ができたらデバッグを開始してみましょう。デバッグの開始は「実行」→「デバッグの開始」(あるいはF5)です。
するとfibonacci関数が呼ばれたところで、実行が止まる(ブレークする)はずです。
ソースコードの4行目がハイライトされ、ここを実行するところでブレークしたことがわかります。
また、画面左側のコールスタックをみるとmain関数からfibonacci関数が実行されたことが、変数を見ると引数nは10であることがわかります。
ここでステップ実行してみましょう。ステップオーバーはF10あるいは下記のボタンです。
ちなみにこのボタンは、左から続行(F5)、ステップオーバー(F10)、ステップイン(F11)、ステップアウト(Shift+F11)、再起動(Ctrl+Shift+F5)、中止(Shift+F5)となります。
これで7行目にハイライトが移動し、n=10のためにif文内には入らなかったことがわかります。
ここで続行(F5)をしてみると、次のように再びfibonacci関数(4行目)でブレークします。コールスタックをみるとmain関数→fibonacci関数→fibonacci関数と呼び出されていることがわかります。
ちなみにこのときの引数が「8」であることがわかります。
このようにVS Codeを使うとLinuxのコマンドを入力することなく、グラフィカルにコーディング・デバッグを行うことができます。
ビルドとデバッグ設定の確認と変更
さて今回はコンパイラはgccを使うように指定しましたが、コンパイラに渡すオプションについては何も指定しませんでした。
これをカスタマイズしてみましょう。
これ以降の記事は結構試行錯誤したところもあります。
よりよい方法があればコメント欄からご指摘いただけると助かります。
ビルド設定の確認
実際にどのようなコンパイルオプションが使用されているのかは、「ターミナル」→「既定のビルドタスクの構成」で表示させることができます。
このメニューを選択すると「既定のビルドタスクとして利用するタスクを選択」としてリストが表示されるので「C/C++:gccアクティブなファイルのビルド(c_test)は既に既定のビルドタスクとしてマークされています」というタスクを選択します。
これでtasks.jsonというファイルが開かれます。
私の場合はこのファイルは次のような内容になっていました。
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc アクティブなファイルのビルド",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "デバッガーによって生成されたタスク。"
}
],
"version": "2.0.0"
}
argsの部分がコンパイラ(gcc)に渡されるオプションです。これをみると「-g」でデバッグ情報を付与していますが、最適化オプションなどは指定されていないことがわかります。
ちなみに「既定のビルドタスクとして利用するタスクを選択」のときに表示された「デバッガーによって生成されたタスク」はこのtasks.jsonの「detail」に対応していることがわかります。
ビルド設定の追加
新たにビルド設定(タスク)を追加してみましょう。
作成したソースファイル(fibonacci.c)が表示されている状態で「ターミナル」→「タスクの構成」を選択します。「構成するタスクの選択」が表示されたら「C/C++:gccアクティブファイルのビルド」を選択しましょう。
すると再びtasks.jsonが表示されますが、tasksリストの中にもう1つタスクが追加されたことがわかります。
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc アクティブなファイルのビルド",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "デバッガーによって生成されたタスク。"
},
{
"type": "cppbuild",
"label": "C/C++: gcc アクティブなファイルのビルド",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "コンパイラ: /usr/bin/gcc"
}
],
"version": "2.0.0"
}
この追加されたタスクをデバッグ用に最適な設定にしてみます。
具体的には、「args」に「最適化を無し(-O0)」、「コンパイルの警告を表示(-Wall)」を追加しましょう。またわかりやすいように「label」と「detail」の記述の修正しておきます。
同様にタスクを追加(コピペでOK)し、こちらはリリース用の設定としてみます。
このようにして修正したtasks.jsonは次のようになります。
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc アクティブなファイルのビルド",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "デバッガーによって生成されたタスク。"
},
{
"type": "cppbuild",
"label": "C/C++: gcc アクティブなファイルのビルド (デバッグ用)",
"command": "/usr/bin/gcc",
"args": [
"-Wall",
"-O0",
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "コンパイラ: /usr/bin/gcc (デバッグ用)"
},
{
"type": "cppbuild",
"label": "C/C++: gcc アクティブなファイルのビルド (リリース用)",
"command": "/usr/bin/gcc",
"args": [
"-Wall",
"-O3",
"-fdiagnostics-color=always",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": "build",
"detail": "コンパイラ: /usr/bin/gcc (リリース用)"
}
],
"version": "2.0.0"
}
この例はあまり意味のない追加かもしれません。
しかし、より複雑なコンパイルオプションを利用するケースもあると思いますので、tasks.jsonの修正方法は覚えておいた方が良さそうです。
これでタスクが2つ追加されましたので試してみましょう。
再びプログラムのソースファイル(fibonacci.c)を表示させた状態で、「ターミナル」→「タスクの実行」を選んでみましょう。
画面上部に「実行するタスクの選択」と表示され、先ほど作成したタスク「C/C++:gccアクティブなファイルのビルド (デバッグ用)」と「C/C++:gccアクティブなファイルのビルド (リリース用)」があるはずです。
ここで「C/C++:gccアクティブなファイルのビルド (リリース用)」を選んでみると、右下のターミナルのエリアに実行されたコマンドが表示されます。
tasks.jsonで指定したように「-Wall」と「-O3」のオプションが付いていることがわかります。
同様に「C/C++:gccアクティブなファイルのビルド (デバッグ用)」を選択すると「-Wall」と「-O0」のオプションでコンパイルされます。
デバッグ構成の変更
さてtasks.jsonを編集してビルド設定(タスク)を追加したら、デバッグ時に利用できるようにしましょう。
利用するのは当然ながら「C/C++:gccアクティブなファイルのビルド (デバッグ用)」です。
「C/C++:gccアクティブなファイルのビルド (リリース用)」で作成される実行ファイルは、デバッグに必要な情報がついていないので、デバッグには不適当です。
ソースファイル(fibonacci.c)が表示されている状態で「実行」→「構成の追加」を選択するとlaunch.jsonというファイルが生成されます。
このlaunch.jsonというファイルはデバッグ(実行)時に行われる処理を記述するものです。
最初はlaunch.jsonの内容は実質ないと思いますので、右下の「構成の追加」を選択します。すると追加する構成(テンプレート)が選べますので「C/C++: (gdb)起動」を選択します。
するとlaunch.jsonにgdbを起動するための設定が挿入され、次のようになります。
{
// IntelliSense を使用して利用可能な属性を学べます。
// 既存の属性の説明をホバーして表示します。
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) 起動",
"type": "cppdbg",
"request": "launch",
"program": "プログラム名を入力してください (例: ${workspaceFolder}/a.out)",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "gdb の再フォーマットを有効にする",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "逆アセンブリ フレーバーを Intel に設定",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
],
}
「configurations」の値(リスト)が、デバッグ(実行)時に行われる処理を示しています。
これはあくまでもテンプレートなので、そのままでは動きません。そこで次のように修正します。
{
// IntelliSense を使用して利用可能な属性を学べます。
// 既存の属性の説明をホバーして表示します。
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "gcc - アクティブファイルのビルドとデバッグ",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "gdb の再フォーマットを有効にする",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "逆アセンブリ フレーバーを Intel に設定",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: gcc アクティブなファイルのビルド (デバッグ用)"
}
],
}
修正したのは「name」「program」の値を変更した点と、「preLaunchTask」を追加した点です。
「preLaunchTask」では、デバッグ(実行)の開始前に実行されるビルド設定(タスク)を指定します。ここでは先ほど作成した「C/C++:gccアクティブなファイルのビルド (デバッグ用)」を指定しました。
このようにすると、ソースファイル(fibonacci.c)が表示されている状態で「実行」→「デバッグの開始」あるいは「実行」→「デバッグ無しで実行」を選ぶと、指定したビルド設定(「-Wall」と「-O0」でビルド)を適用してビルドした後に、デバッグあるいは実行できます。
まとめ
今回はWSL2でLinuxを導入したWindowsにVS Codeをインストールして、C言語を使ってみました。
拡張機能の「Remote Development」と「WSL」を使ってVS CodeとWSL2を連携させると、Linuxのコマンドラインを一切使わずに、LinuxでC言語のプログラムをコンパイル・デバッグできます。かなり開発の敷居が下がるのではないでしょうか。
次回は「Remote – SSH」拡張機能を使って同様のことをやってみたいと思います。
コメント