VSCodeでは、プロジェクトのルートフォルダにMakefileを作成し、統合ターミナルからmakeコマンドを実行することで、ビルドやテスト、ファイル削除などの処理を自動化できます。
MakefileはCやC++のコンパイルでよく使われますが、C/C++専用の仕組みではありません。
Pythonのテスト実行、JavaScriptのビルド、Dockerイメージの作成、デプロイスクリプトの実行など、コマンドラインで処理できる内容であれば幅広く利用できます。
VSCodeとMakefileを組み合わせることで、複数のコマンドを毎回手入力する必要がなくなり、開発作業を効率化できます。
VSCodeでMakefileを使うために必要なもの
VSCodeでMakefileを利用するには、VSCodeだけでなく、makeコマンドを実行できる環境が必要です。
VSCode自体にGNU Makeが内蔵されているわけではありません。
VSCodeはMakefileを編集したり、統合ターミナルから外部コマンドを実行したりするための開発環境です。
主に必要になるものは次のとおりです。
- Visual Studio Code
- GNU Makeなどの
makeコマンド - 必要に応じてGCCやClangなどのコンパイラ
たとえばC言語のプログラムをMakefileからビルドする場合、makeだけでなくgccなどのコンパイラも必要です。
makeがインストールされているか確認する
まずは、現在の環境でmakeを利用できるか確認しましょう。
VSCodeの統合ターミナルを開く
VSCodeの上部メニューから、次の順番で開きます。
ターミナル
↓
新しいターミナル
WindowsやLinuxでは、一般的に次のショートカットでもターミナルを開けます。
Ctrl + `
統合ターミナルを開いたら、次のコマンドを入力します。
make --version
GNU Makeが正常にインストールされていれば、次のようなバージョン情報が表示されます。
GNU Make 4.x
Copyright (C) Free Software Foundation, Inc.
...
このように表示されれば、Makefileを実行する準備はできています。
makeが見つからない場合
次のようなエラーが表示される場合があります。
make: command not found
Windowsでは、次のようなメッセージが表示されることもあります。
'make' is not recognized as an internal or external command
この場合は、GNU Makeがインストールされていないか、PATHが正しく設定されていない可能性があります。
Windowsでmakeをインストールする方法
Windowsには、GNU Makeが標準では含まれていない環境が多いため、別途導入する必要があります。
代表的な方法としては、次のようなものがあります。
- MSYS2
- WSL
- MinGW系の開発環境
- Chocolateyなどのパッケージマネージャー
MSYS2を利用する場合
Windows上でUnix系の開発ツールを利用したい場合は、MSYS2が便利です。
MSYS2をインストールしたあと、MSYS2のターミナルから次のように実行できます。
pacman -S make
インストール後は、次のコマンドで確認します。
make --version
MSYS2では通常のGNU Makeであるmakeを利用できます。
環境によってはmingw32-makeというコマンドも存在しますが、一般的なMakefileでは通常のmakeを利用する方が扱いやすい場合があります。
WSLを利用する場合
Linuxに近い開発環境をWindows上で利用したい場合は、WSLも便利です。
Ubuntuを使用している場合は、次のように実行できます。
sudo apt update
sudo apt install build-essential
build-essentialには、GNU MakeやGCCなど、C/C++開発でよく利用するツールが含まれています。
Makeだけが必要な場合は、次のようにインストールすることもできます。
sudo apt install make
macOSでmakeを利用する方法
macOSでは、Xcode Command Line Toolsをインストールすることで、makeなどの開発ツールを利用できます。
ターミナルから次のコマンドを実行します。
xcode-select --install
インストール後、次のコマンドで確認できます。
make --version
なお、macOSに標準で用意されるmakeと、Homebrewなどから導入するGNU Makeでは、バージョンや細かな挙動が異なる場合があります。
Linuxでmakeをインストールする方法
UbuntuやDebian系Linuxでは、次のようにインストールできます。
sudo apt update
sudo apt install make
CやC++の開発環境もまとめて導入したい場合は、次の方法があります。
sudo apt install build-essential
Fedora系Linuxでは、次のようにインストールできます。
sudo dnf install make
VSCodeでMakefileを作成する
makeが利用できるようになったら、VSCodeでMakefileを作成します。
プロジェクトフォルダを作成する
たとえば、次のような構成を考えます。
sample/
├── main.c
└── Makefile
VSCodeでsampleフォルダを開き、エクスプローラーから新しいファイルを作成します。
ファイル名は、一般的に次のようにします。
Makefile
通常は拡張子を付けません。
Makefile.txt
ではなく、次のようにします。
Makefile
GNU MakeはGNUmakefile、makefile、Makefileなどを自動的に探しますが、一般的にはMakefileという名前を使用すると分かりやすいでしょう。
Makefileの基本的な書き方
Makefileは、基本的に次のような構造で記述します。
ターゲット: 依存ファイル
実行するコマンド
このとき、実行するコマンドの部分を「レシピ」と呼びます。
最も簡単なMakefile
たとえば、次のように書きます。
hello:
echo "Hello Make!"
echoの前には、通常タブ文字を使用します。
保存したあと、VSCodeの統合ターミナルで次のように実行します。
make
すると、次のような結果が表示されます。
echo "Hello Make!"
Hello Make!
ここでは、helloがターゲットです。
その下にある、
echo "Hello Make!"
が実行されるレシピです。
Makefileではタブとスペースに注意する
Makefile初心者が特につまずきやすいのが、レシピ部分のインデントです。
通常のMakefileでは、レシピ行の先頭にタブ文字を使用します。
たとえば、次のように書きます。
hello:
echo "Hello"
一方、スペースでインデントすると、次のようなエラーになる場合があります。
*** missing separator. Stop.
VSCodeではタブとスペースの見た目が分かりにくいことがあります。
Makefileでmissing separatorが表示された場合は、まずレシピ部分のインデントを確認するとよいでしょう。
GNU Makeにはタブ以外の接頭辞を設定する方法もありますが、一般的なMakefileではタブを使用するのが基本です。
C言語をMakefileでコンパイルする
Makefileの代表的な用途が、CやC++のコンパイルです。
main.cを作成する
たとえば、main.cを次のように作成します。
#include <stdio.h>
int main(void)
{
printf("Hello, Make!\n");
return 0;
}
続いてMakefileを作成します。
main: main.c
gcc main.c -o main
makeを実行する
VSCodeの統合ターミナルで、次のように実行します。
make
MakeはMakefileを読み込み、実質的に次のコマンドを実行します。
gcc main.c -o main
コンパイルに成功すると、実行ファイルが作成されます。
LinuxやmacOSでは、一般的に次のように実行できます。
./main
Windowsでは、環境やシェルによって次のように実行します。
.\main.exe
WSLやMSYS2などのUnix系シェルを利用している場合は、Windows上でも./mainのような書き方が利用できる場合があります。
makeでターゲットを指定する
Makefileには、複数のターゲットを定義できます。
たとえば、次のように記述します。
build:
gcc main.c -o main
run:
./main
clean:
rm -f main
それぞれ、次のように実行できます。
make build
make run
make clean
基本的な形式は次のとおりです。
make ターゲット名
ターゲットを指定しない場合
単純に、
make
と実行した場合、通常はMakefile内で最初に定義された通常のターゲットがデフォルトゴールとして使用されます。
たとえば、
build:
gcc main.c -o main
run:
./main
なら、makeだけを実行するとbuildが対象になります。
allターゲットを利用する
Makefileでは、プロジェクト全体をビルドするターゲットとしてallという名前がよく使われます。
たとえば、次のように書きます。
all: main
main: main.c
gcc main.c -o main
この場合、
make
を実行すると、最初のターゲットであるallが対象になります。
allはmainに依存しているため、最終的にmainがビルドされます。
なお、allはGNU Makeの予約語ではありません。
プロジェクト全体をビルドするターゲット名として広く使われている慣習です。
Makefileの依存関係を理解する
Makeの大きな特徴は、ターゲットと依存ファイルの関係を管理できることです。
たとえば、次のMakefileを考えます。
main: main.c
gcc main.c -o main
この場合、
main
がターゲットで、
main.c
が依存ファイルです。
Makeは、ターゲットと依存ファイルの更新日時などを確認し、再ビルドが必要かどうかを判断します。
一度、
make
を実行したあと、main.cを変更せずにもう一度、
make
を実行すると、次のようなメッセージが表示される場合があります。
make: 'main' is up to date.
つまり、変更されていないファイルを毎回ビルドする必要がありません。
ソースファイルを変更すると、必要なターゲットだけが再ビルドされます。
複数のソースファイルをコンパイルする
実際のCやC++プロジェクトでは、複数のソースファイルを利用することがあります。
たとえば、次のような構成です。
sample/
├── main.c
├── calculator.c
├── calculator.h
└── Makefile
Makefileは次のように書けます。
main: main.o calculator.o
gcc main.o calculator.o -o main
main.o: main.c calculator.h
gcc -c main.c
calculator.o: calculator.c calculator.h
gcc -c calculator.c
このように依存関係を記述すると、変更されたソースファイルに関係する部分だけを再コンパイルできます。
Makefileで変数を使う
同じコンパイラ名やオプションを何度も記述する場合は、変数を使うと管理しやすくなります。
たとえば、次のように書きます。
CC = gcc
CFLAGS = -Wall -Wextra
main: main.c
$(CC) $(CFLAGS) -o main main.c
ここでは、
CC = gcc
で使用するコンパイラを指定しています。
また、
CFLAGS = -Wall -Wextra
でコンパイルオプションを設定しています。
実際には、次のようなコマンドが実行されます。
gcc -Wall -Wextra -o main main.c
コンパイラを変更したい場合も、CCの値を変更するだけで済みます。
.PHONYを使う
cleanやrunなど、実際のファイルを作成することを目的としないターゲットには、.PHONYを指定する方法があります。
たとえば、次のように書きます。
.PHONY: all run clean
all: main
main: main.c
gcc main.c -o main
run: main
./main
clean:
rm -f main
.PHONYを指定することで、all、run、cleanが実ファイルではなく、処理を実行するためのターゲットであることをMakeに伝えられます。
たとえば、プロジェクト内に偶然cleanという名前のファイルが存在していたとしても、
make clean
を実行すれば、cleanのレシピが実行されます。
パターンルールを利用する
ソースファイルが増えてくると、ファイルごとにコンパイルルールを書くのが大変になります。
その場合は、パターンルールを利用できます。
たとえば、次のように書きます。
CC = gcc
CFLAGS = -Wall -Wextra
TARGET = app
SRCS = main.c calculator.c
OBJS = $(SRCS:.c=.o)
.PHONY: all run clean
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(OBJS) -o $(TARGET)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
run: $(TARGET)
./$(TARGET)
clean:
rm -f $(TARGET) $(OBJS)
ここで、
%.o: %.c
は、「.cファイルから対応する.oファイルを作成する」というパターンルールです。
また、
$<
は最初の依存ファイルを表します。
$@
は現在のターゲットを表します。
たとえば、main.cからmain.oを作る場合、
$(CC) $(CFLAGS) -c $< -o $@
は実質的に、
gcc -Wall -Wextra -c main.c -o main.o
のように展開されます。
VSCodeのTasksからmakeを実行する
毎回ターミナルからmakeを入力しても問題ありませんが、VSCodeのTasks機能と組み合わせることもできます。
tasks.jsonを作成する
プロジェクト内に次のファイルを作成します。
.vscode/tasks.json
たとえば、次のように設定します。
{
"version": "2.0.0",
"tasks": [
{
"label": "Make Build",
"type": "shell",
"command": "make",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": []
}
]
}
この設定をすると、VSCodeからビルドタスクとしてmakeを実行できます。
make cleanやmake runをTaskに登録する
複数のMakeターゲットをVSCode Tasksとして登録することもできます。
たとえば、次のように設定します。
{
"version": "2.0.0",
"tasks": [
{
"label": "Make",
"type": "shell",
"command": "make",
"problemMatcher": []
},
{
"label": "Make Clean",
"type": "shell",
"command": "make",
"args": [
"clean"
],
"problemMatcher": []
},
{
"label": "Make Run",
"type": "shell",
"command": "make",
"args": [
"run"
],
"problemMatcher": []
}
]
}
make cleanと1つの文字列で記述する方法もありますが、commandとargsを分ける方が設定内容を理解しやすくなります。
Taskを実行する
VSCodeのコマンドパレットを開き、
Tasks: Run Task
を選択します。
登録した、
Make
Make Clean
Make Run
などのタスクから、実行したい処理を選べます。
WindowsでMakefileを使うときの注意点
Windowsでは、Makefile自体は正しくても、レシピ内のコマンドが実行できない場合があります。
rmコマンドに注意する
たとえば、次のMakefileです。
clean:
rm -f main
rmはUnix系のコマンドです。
Linux、macOS、WSL、MSYS2、Git Bashなどでは利用できますが、Windowsの環境によっては利用できません。
Makefile内で利用できるコマンドは、OSだけでなく、Makeが使用しているシェルやPATHの設定にも影響されます。
./mainにも注意する
次のような記述もUnix系の環境では一般的です。
run:
./main
LinuxやmacOS、WSLなどでは問題ありません。
一方、Windows PowerShellでは、手動で実行する場合、
.\main.exe
のように記述することがあります。
WindowsとLinux・macOSの両方で同じMakefileを利用したい場合は、OSやシェルの違いを考慮する必要があります。
Makefileが実行できない場合の対処法
Makefileが正常に動かない場合は、エラーメッセージを確認すると原因を特定しやすくなります。
make: command not foundと表示される
次のようなエラーです。
make: command not found
GNU Makeがインストールされていないか、PATHが正しく設定されていない可能性があります。
まず、次のコマンドを実行します。
make --version
バージョン情報が表示されなければ、Makeのインストール環境を確認しましょう。
missing separatorと表示される
次のようなエラーが表示されることがあります。
*** missing separator. Stop.
代表的な原因は、レシピ行のインデントです。
次のようにスペースを使用している場合、
hello:
echo "Hello"
通常はタブに変更します。
hello:
echo "Hello"
VSCodeの設定によっては、Tabキーを押してもスペースに変換される場合があります。
Makefileを編集するときは、実際にタブ文字が入力されているか確認するとよいでしょう。
No rule to make targetと表示される
次のようなエラーです。
No rule to make target ...
これは、必要なターゲットや依存ファイルを作成する方法をMakeが見つけられない場合に発生します。
たとえば、
main: mian.c
gcc mian.c -o main
のようにファイル名を間違えていると、エラーになる可能性があります。
確認するポイントは次のとおりです。
- ファイル名にスペルミスがないか
- 依存ファイルが実際に存在するか
- 必要なビルドルールが定義されているか
- ディレクトリの指定が正しいか
No targets specified and no makefile foundと表示される
次のようなエラーです。
No targets specified and no makefile found
現在のディレクトリにMakefileが存在しない場合などに表示されます。
LinuxやmacOS、WSLなどでは、
pwd
で現在のディレクトリを確認できます。
PowerShellでは、
Get-Location
でも確認できます。
Makefileが別のフォルダにある場合は、
cd フォルダ名
で移動してから、
make
を実行します。
MakefileはC/C++以外でも使える
MakefileはCやC++専用ではありません。
コマンドラインから実行できる処理であれば、さまざまな作業を登録できます。
Pythonで利用する例
test:
pytest
実行すると、
make test
でPythonのテストを実行できます。
JavaScriptで利用する例
lint:
npm run lint
次のコマンドで実行できます。
make lint
Dockerで利用する例
docker-build:
docker build -t myapp .
次のように実行できます。
make docker-build
複雑なコマンドを覚えておかなくても、短いターゲット名で実行できるのがMakefileのメリットです。
VSCodeとMakefileの役割を理解する
VSCodeとMakefileの関係を整理すると、次のようになります。
VSCode
↓
統合ターミナル
↓
make
↓
Makefileを読み込む
↓
必要なターゲットを判断する
↓
gccなどの外部コマンドを実行する
↓
実行ファイルなどを生成する
VSCodeは、Makefileを編集したり、ターミナルからコマンドを実行したりするためのエディタです。
Makefileは、「何をどのように作るか」を定義する設定ファイルです。
makeはMakefileを読み込み、どの処理が必要なのかを判断するプログラムです。
gccなどのコンパイラは、実際にソースコードをコンパイルします。
それぞれの役割を分けて理解すると、Makefileの仕組みが分かりやすくなります。
VSCodeでMakefileを使う基本的な流れ
VSCodeでMakefileを利用する流れをまとめると、次のようになります。
- GNU Makeをインストールする
- 必要に応じてGCCやClangなどをインストールする
- VSCodeでプロジェクトフォルダを開く
- プロジェクト内に
Makefileを作成する - ターゲット、依存関係、レシピを書く
- VSCodeの統合ターミナルを開く
makeを実行する- 必要に応じて
make runやmake cleanを実行する
たとえば、最初は次のようなシンプルなMakefileから始めるとよいでしょう。
.PHONY: all run clean
all: main
main: main.c
gcc -Wall -Wextra main.c -o main
run: main
./main
clean:
rm -f main
ビルドするときは、
make
実行するときは、
make run
生成ファイルを削除するときは、
make clean
とします。
まとめ
VSCodeでMakefileを利用するには、まずGNU Makeを利用できる環境を用意し、プロジェクト内にMakefileを作成します。
Makefileでは、基本的に次の形式で処理を定義します。
ターゲット: 依存ファイル
実行するコマンド
VSCodeの統合ターミナルから、
make
を実行すると、Makefileが読み込まれ、必要な処理だけが実行されます。
また、
make run
make clean
のように複数のターゲットを用意しておけば、ビルド、実行、削除などの処理を簡単なコマンドで呼び出せます。
さらにVSCodeのtasks.jsonと組み合わせれば、MakeをVSCodeのビルドタスクとして登録することも可能です。
Makefileを初めて使う場合は、最初から複雑な記述を覚える必要はありません。
まずは、
1つのターゲットを作る
↓
makeで実行する
↓
依存関係を追加する
↓
変数を使う
↓
.PHONYを使う
↓
複数ファイルのビルドに発展させる
という順番で覚えると理解しやすいでしょう。
Makefileの基本を身につけると、VSCodeでのビルドやテスト、実行といった定型作業を効率よく自動化できるようになります。
以上、VSCodeでMakefileを作成・実行する方法についてでした。
最後までお読みいただき、ありがとうございました。










