makeで環境変数とMakefileの変数、引数の値の内どの値が参照されるか
linux$ docker run -v `pwd`:/root -it ubuntu:20.04 /bin/sh
# apt update && apt install -y make
# make --version
GNU Make 4.2.1
Built for x86_64-pc-linux-gnu
# cat Makefile
HOGE:=aaa
foo:
echo $(HOGE) $(FUGA) > /dev/null
フラグを付けないと引数の値 -> Makefileの変数 -> 環境変数
の順で参照されるので、
makeの前に書いた環境変数ではMakefileの変数を上書きできず、後に書いて引数とすると上書きできる。
# export HOGE=ccc FUGA=ddd
# make foo
echo aaa ddd > /dev/null # (Makefileの変数 > 環境変数) (環境変数)
# HOGE=bbb FUGA=xxx make foo
echo aaa xxx > /dev/null # (Makefileの変数 > 環境変数) (環境変数)
# make foo HOGE=bbb FUGA=xxx
echo bbb xxx > /dev/null # (引数の値 > Makefileの変数) (引数の値)
-e
フラグを付けて実行すると環境変数の優先度が上がり引数の値 -> 環境変数 -> Makefileの変数
の順で参照されるようになる。
# make --help
...
-e, --environment-overrides Environment variables override makefiles.
# make -e foo
echo ccc ddd > /dev/null # (環境変数 > Makefileの変数) (環境変数)
# make -e foo HOGE=bbb FUGA=xxx
echo bbb xxx > /dev/null # (引数の値 > Makefileの変数) (引数の値)
Makefileの変数にoverride
を付けるとその変数は最優先で参照される。
foo: AAA=BBB
のように書くとターゲット特有の変数を定義することができ、overrideと組み合わせるとそのターゲット限定で値を固定できる。
# cat Makefile
foo: override HOGE=@@@
foo:
echo $(HOGE) $(FUGA) > /dev/null
bar:
echo $(HOGE) $(FUGA) > /dev/null
# make foo HOGE=bbb FUGA=xxx
echo @@@ xxx > /dev/null # (Makefileの変数 > 引数の値) (引数の値)
# make bar HOGE=bbb FUGA=xxx
echo bbb xxx > /dev/null # (引数の値 > Makefileの変数) (引数の値)
ちなみに-C
フラグでパスを指定するとそこに移動してから実行されるが、そのときの$(PWD)
は元のパスとなる。$(shell pwd)
で移動した先のパスが取れる。
# cat dir1/Makefile
foo:
echo $(PWD) $(shell pwd) > /dev/null
# make -C dir1 foo
make: Entering directory '/root/dir1'
echo /root /root/dir1 > /dev/null
make: Leaving directory '/root/dir1'