☠️
Makefile入門|Goで学ぶ、はじめてのMakefile
はじめに
Goでプログラムを書いていると、
go buildgo rungo test
…など、毎回同じコマンドを入力するのが面倒になることありませんか?
そんなときに便利なのが Makefile です。
公式ドキュメントでは「依存関係に応じて必要な処理だけを実行するツール」と説明されていますが、Goプロジェクトに限って言えば 「よく使うコマンドをまとめておける便利な仕組み」 と考えるとわかりやすいです。
最小のMakefileを書いてみる
まずはGoで「Hello, World」を出力するプログラムを作りましょう。
main.go
package main
import "fmt"
func main() {
fmt.Println("Hello, World")
}
このプログラムをビルド・実行・削除できるMakefileは次の通りです。
Makefile
APP_NAME = hello
build:
@echo "==> Building..."
go build -o $(APP_NAME) main.go
run: build
@echo "==> Running..."
./$(APP_NAME)
clean:
@echo "==> Cleaning..."
rm -f $(APP_NAME)
実行してみる
$ make build
==> Building...
$ make run
==> Running...
Hello, World
$ make clean
==> Cleaning...
ポイントは:
-
build→ バイナリを生成 -
run→buildに依存し、ビルド後に実行 -
clean→ 生成物を削除(いわゆる phonyターゲット)
ここで学んでほしいのは「Makefileがコマンドのショートカットになっている」ということです。
Goプロジェクトでよく使うターゲット例
Goのプロジェクトでは次のようなターゲットを定義することが多いです。
Makefile
APP_NAME = myapp
.PHONY: build run test fmt lint clean
build:
go build -o $(APP_NAME) ./...
run:
./$(APP_NAME)
test:
go test ./...
fmt:
go fmt ./...
lint:
golangci-lint run ./...
clean:
rm -f $(APP_NAME)
実行イメージ
-
make build→ プロジェクトをビルド -
make run→ 実行 -
make test→ テスト実行 -
make fmt→ フォーマット -
make lint→ 静的解析 -
make clean→ バイナリ削除
チームで開発している場合でも「みんなが同じコマンド体系で操作できる」ので、環境差異や操作ミスを減らせます。
おわりに
Goの開発でMakefileを使うと、
- コマンド入力の手間が減る
- チーム全員が同じ作業手順を使える
- CI/CDに組み込みやすい
といったメリットがあります。
まずは build / run / test あたりをMakefileにまとめてみてください。
その後で lint や fmt、さらにCI向けのターゲットを追加していけば、プロジェクト専用の 便利コマンド集 に育っていきます
Discussion