December 06, 2020
デフォルトターゲット
make は make all
のようにターゲットを指定せずただ make
だけでも実行できます。
その際に何が実行されるかというと、「デフォルトゴール(.DEFAULT_GOAL
)」に指定されたターゲットが実行されます。
.PHONY: help
.DEFAULT_GOAL := help
help:
echo $@
$ make -f 01.mk
echo help
help
.DEFAULT_GOAL
は明記しなければ Makefile 内の最初のターゲットが自動的に設定されます。
.PHONY: help all
$(info default goal is $(.DEFAULT_GOAL))
help:
echo $@
$(info default goal is $(.DEFAULT_GOAL))
all:
echo $@
$(info default goal is $(.DEFAULT_GOAL))
$ make -f 02.mk
default goal is
default goal is help
default goal is help
echo help
help
そのため、ターゲットの指定なしで実行されて構わないターゲットを最初に書くようにすれば、.DEFAULT_GOAL
を明記する必要はありません。
.PHONY: help
help:
echo $@
$ make -f 03.mk
echo help
help
$(info ...)
は make の関数です。ただ引数を出力するだけで、Makefile の動作を確認する際に使います。
自身を cat する help
よくわからずターゲットの指定なしで make
を叩いてしまうときのために、デフォルトゴールとして「自身を cat する help ルール」をの先頭に書くのはよいプラクティスだと思います。
副作用がないですし、内容を読めば次のステップに進む情報を得られるからです。
.PHONY: help build
help:
cat 04.mk
build:
# command ...
$ make -f 04.mk
cat 04.mk
.PHONY: help build
help:
cat 04.mk
build:
# command ...
明示的に cat するファイル名を書くのはメンテナンス性がいまいちですし、
実行結果に cat 04.mk
の行が出てくるのも内容を読むのには邪魔です。
そこで使うのが @
$(firstword ...)
$(MAKEFILE_LIST)
です。
これで出力が読みやすくなって、ファイル名が変わっても問題なく動くようになりました。
.PHONY: help
help:
@cat $(firstword $(MAKEFILE_LIST))
build:
# command ...
$ make -f 05.mk
.PHONY: help
help:
@cat $(firstword $(MAKEFILE_LIST))
build:
# command ...
@
@
は「レシピ出力(Recipe Echoing)を抑制する記号です。
通常 make はコマンドを出力しますが、@
で始まるコマンド行は出力しません。
ただ、コマンドを出力するのがデフォルトの挙動なので、特別な理由がない限りつけない方がよいでしょう。
すべての行に @
をつけて回るのはツールの使い方として間違っていないでしょうか。
$(MAKEFILE_LIST)
$(MAKEFILE_LIST)
は make がパースした Makefile のリストです。
通常は実行対象の Makefile だけが与えられますが、他の Makefile を include
した場合、複数のファイル名が与えられます。
.PHONY: info run
info:
echo $(MAKEFILE_LIST)
run:
echo NAME=$(NAME)
echo HOGE=$(HOGE)
echo FUGA=$(FUGA)
include hoge.mk fuga.mk
# hoge.mk
NAME := hoge
HOGE := hoge
# fuga.mk
NAME := fuga
FUGA := fuga
$ make -f 06.mk info
echo 06.mk hoge.mk fuga.mk
06.mk hoge.mk fuga.mk
$ make -f 06.mk run
echo NAME=fuga
NAME=fuga
echo HOGE=hoge
HOGE=hoge
echo FUGA=fuga
FUGA=fuga
$(firstword ...)
$(firstword ...)
はリストから最初の要素を取り出す関数です。
.PHONY: list
LIST := hoge fuga vaa
list:
echo $(firstword $(LIST))
$ make -f 07.mk list
echo hoge
hoge
$(MAKEFILE_LIST)
はパースした順にファイル名を格納します。cat したいのはユーザが実行した Makefile であることがほとんどなので、@cat $(firstword $(MAKEFILE_LIST))
が常用句になっています。
多少複雑なので最初は @cat Makefile
でもよいと思いますが、慣れると脳死で書き始められて便利です。