はじめに
Golang開発のタスクランナーとしてMakefileを利用することが多いようなので書き方を整理します。
サンプル
タスク
タスクの実行
terminal
$ make taskname
タスクの設定
Makefile
.PHONY: taskname
taskname:
command
# 実行コマンド非表示
.PHONY: taskname
taskname:
@command
# タスク定義が複数のコマンド
.PHONY: taskname
taskname:
command1
command2
# 複数コマンドをワンライナーで実行
.PHONY: taskname
taskname:
command1 && command2
# 上のケースの別の方法
.PHONY: taskname
taskname:
command1 ; command2 ;\
command3
# タスクの前に別のタスクを実行
.PHONY: taskname3
taskname3: taskname1 taskname2
command
# 自身のMakefileに定義してある別のタスク定義を実行
.PHONY: taskname2
taskname2:
$(MAKE) taskname1
command
.PHONYについて
タスク名と同名のファイルやディレクトリがあるとタスクが実行されません。
.PHONYは省略可能ですが、定義することで上記の条件でも実行が可能になるため
基本的には書いていこうかと思います。
変数
Makefile
# 変数名=値
VAR=hello make
.PHONY: taskname
taskname:
echo $(VAR)
# shell commandの実行結果を変数に格納
NOW=$(shell date)
.PHONY: taskname
taskname:
echo $(NOW)
# シェルスクリプト変数・環境変数は$$で参照
.PHONY: taskname
taskname:
VAR=$$GOPATH && echo $$VAR
# タスク実行中に環境変数を書き換えたい場合は、コマンド実行が1行終わるごとに環境変数がmakeコマンド実行時に戻る
.PHONY: taskname
taskname:
export VAR="この値は消えてしまいます"
echo VAR=$${VAR}
.PHONY: taskname
taskname:
export VAR="この値は残ります" ;\
echo VAR=$${VAR}
# サブディレクトリのMakefileのタスクを実行する
.PHONY: taskname
taskname:
make -C sub_directory sub_task
# make実行時に変数の値を渡す(make task VAR=XXX)
VAR="これは上書きされる"
.PHONY: taskname
taskname:
echo $(VAR) $$VAR
OSSプロダクトのMakefileを見てみる
Docker
kubernetes
Terraform
Gobot
Gin
.PHONYは全てのタスクで定義
参考のmakefileでは全てのタスクで.PHONYが定義されていました
一括で.PHONYを定義することもできる
.PHONY: bin cover default dev e2etest fmt fmtcheck generate protobuf plugin-dev quickdev test-compile test testacc testrace tools vendor-status website website-test
よく見かけたタスク
以下のタスクをよく見かけました
- fmt
- test
- lint/vet
- clean
- help
タスクの詳細はshellを用意
複雑なタスクはshellを用意し、Makefileは実行だけするようにしていた箇所がいくつかありました
ifeqで条件分岐
Makefile
ifeq ($(XXX),y)
taskname:
command1
else
taskname:
command2
endif