makeの変数展開

最近、exportしたmake変数の展開方法でかなり悩まされた。
↓とか買えば載ってるんだろうか?

GNU Make 第3版

GNU Make 第3版


一応、自分で調べて勝手に納得した内容。
↓のように自動変数$@(ターゲット)を含む変数がexportされている場合の挙動。

- main.gmk:

export FOO = $$@
export BAR = $@

main:
   @echo "FOO = $(FOO)"
   @echo "BAR = $(BAR)"
   make -f sub.gmk

- sub.gmk

sub:
    @echo "FOO = $(FOO)"
    @echo "BAR = $(BAR)"
    make -f subsub.gmk

- subsub.gmk

subsub:
   @echo "FOO = $(FOO)"
   @echo "BAR = $(BAR)"

この場合、mainではいつも通り、$$ -> $ の変換がかかってシェルには

   echo "FOO = $@"
   echo "BAR = main"

というコマンドが渡る。最終的には $@ なんて変数はシェル環境にはなかったりするので

FOO = 
BAR = main

みたいな表示になるが、今回はシェルでの解釈は本題ではないので、これ以降無視。


興味深いのがsubでの展開方法。以前は、subでもmainと同じように

   echo "FOO = $@"
   echo "BAR = sub"

という展開になるんだろうと思っていたが、そうならない。

   echo "FOO = sub"
   echo "BAR = main"

になる!じゃあ、subsubはというと、

   echo "FOO = subsub"
   echo "BAR = main"

これはつまり、FOOは$@を保持し続けているのに、BARはmainで$@がmainに変換されているってこと?

最終的には、mainからsubを呼び出すときに、exportと宣言された変数をsubに渡す前に環境変数化す
るときに、一度展開が入るんだろうと言う結論になりました。subからsubsubを呼び出すときには
すでに、FOOは環境変数化されているので、もう一回環境変数化の処理が入ることがない。
これによってsubsubではFOOを$@だと解釈していると。