![Makefile依存関係で`[email protected]`を使用すると動作しません](https://rvso.com/image/191962/Makefile%E4%BE%9D%E5%AD%98%E9%96%A2%E4%BF%82%E3%81%A7%60%5Bemail%20protected%5D%60%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%81%A8%E5%8B%95%E4%BD%9C%E3%81%97%E3%81%BE%E3%81%9B%E3%82%93.png)
次のような Makefile ルールを試しても機能しませんでした (GNU Make 4.0)。
foo: [email protected] other.o
bar: bar.o other.o
ファイルはfoo.c
( にfoo.o
) コンパイルされましたが、リンク コマンドは でしたcc -o .o
。
対照的に、bar
は として正しくコンパイルされ、リンクされましたcc bar.o other.o -o bar
。
その違い(または問題)を説明できる人はいますか?
答え1
これについては、自動変数GNU Make マニュアル:
自動変数値が使用できる範囲が限られていることを認識しておくことは非常に重要です。自動変数値はレシピ内でのみ値を持ちます。特に、ルールのターゲット リスト内のどこでも自動変数値を使用することはできません。自動変数値には値がなく、空の文字列に展開されます。また、ルールの前提条件リスト内で直接アクセスすることもできません。よくある間違いは、
$@
前提条件リスト内で使用しようとすることですが、これは機能しません。
段落の残りの部分では、GNU Make 固有のものではありますが、1 つの可能な解決策が示されています。二次拡大. Makefileを次のように記述します
.SECONDEXPANSION:
foo: [email protected] other.o
bar: bar.o other.o
適切な値を与えることができ$$@
、その後
$ make foo
cc -c -o foo.o foo.c
cc -c -o other.o other.c
cc foo.o other.o -o foo
期待通りの動作をします。
(私の経験では、二次的な拡張に頼るよりも問題に対処するより良い方法があることが多いのですが、それは、何をしようとしているのかという全体的な目標を理解することによってのみ判断できます。)