知りたかったこと
makeを実行するときの変数の指定の仕方は
HOGE=env make
と
make HOGE=arg
がある。前者はシェルによって解釈され、後者はmake自身が解釈するのだが、実行にどう違いが出るのか?
Makefile内で変数の書き方は
# exportしない
HOGE=noexp
と
export HOGE=exp
がある。どう違うのか?
サブディレクトリ内でmakeする書き方は
$(MAKE) -C sub
と
$(MAKE) -e -C sub
がある。どう違うのか?
実際には
cd subdir && $(MAKE)
という書き方もあるが、これは$(MAKE) -C subdir
と同じである。
これらの違いを知りたかったので、実験してみた。
実験結果
変数定義の優先順位
環境変数<ファイル内に書いた値<makeの引数
となる。つまり、
HOGE=file
all:
echo $(HOGE)
と書いて
HOGE=env make HOGE=arg
で実行した場合、結果はarg
が表示される。
HOGE=env make
で実行した場合、file
が表示される。
Makefile内のHOGE=file
を消して
HOGE=env make
で実行した場合、env
が表示される。
親makeから子makeへの変数の伝播の仕方
- 親から子へ伝わるかどうか
- 子で定義されている変数を上書きするかどうか
を表にするとこうなる:
-eなし | -eあり | |
---|---|---|
make HOGE=arg | 伝わる。上書きする | 伝わる。上書きする |
HOGE=env make | 伝わる。上書きしない | 伝わる。上書きする |
export HOGE=file1 | 伝わる。上書きしない | 伝わる。上書きする |
HOGE=file1 | 伝わらない。上書きしない | 伝わらない。上書きしない |
まとめ
- 変数の優先順位は、環境変数<ファイル内に書いた値<makeの引数
- exportした場合は環境変数と同じ扱いになる。したがって子に伝播する
- exportしない場合はシェルにおけるシェル変数と同じく、自プロセス内でのみ有効(子に伝播しない)
- 基本的に親ファイルに書いた変数は子ファイルに書いた変数を上書きしないが、
-e
をつけると上書きするようになる - コマンドラインの引数で指定した場合(
make HOGE=arg
)は常に子ファイルの変数を上書きする