2012-03-13 11 views
23

私はGNU make 3.81を使用しています。ここでは、問題を示していたテストのmakefileは次のとおりです。マクロを使ってforeach内で複数のMakefileターゲット/ルールを生成するにはどうすればよいですか?不思議な挙動

define BOZO 

a$(1): b c 
    touch a$(1) 

endef 

$(foreach i,1 2 3,$(call BOZO,$(i))) 

ここでの考え方は、予測可能なパターンに従うルールを生成するために、マクロテンプレート(ボゾ)を使用することです。

問題:(ライン10は、foreachのとラインの場合)

Makefile.fake:10: *** multiple target patterns. Stop. 

:私はこのメイクファイルでmakeを実行したときに、私はというエラーを取得します。

ここで、そのエラーが通常示していることを知っています。 info関数を使って拡張を標準出力に送ることで、その行がどのように展開するのかを見てみましょう。

$(info $(foreach i,1 2 3,$(call BOZO,$(i)))) 

と私は実行します:私はあることを10行に変更

$ make -n 

a1: b c 
    touch a1 

a2: b c 
    touch a2 

a3: b c 
    touch a3 

make: *** No targets. Stop. 

「無ターゲット」のメッセージが期待されていることに注意してください、$(情報...)関数は、空にすることを評価するのでなく、生成されたルールをに印刷にします。

これらのルールを実行しましょうか?

$make -n > out.txt 
make: *** No targets. Stop. 
$make -f out.txt a1 a2 a3 
touch a1 
touch a2 
touch a3 
$ 

AAARGH!ルールは正常に動作します。だから...作るか、私の理解のバグですか?その後、

$(foreach i,1,$(call BOZO,$(i))) 

(ようにforeachのは一つだけの繰り返しを持っている)

$make a1 

の操作を行います。私はforeachのラインを変更した場合:

一つの最終診断に役立つかもしれない手がかり別のエラーが発生する:

make: *** No rule to make target `a1'. Stop. 

$(foreach)の拡張子が「$(info)」以外のものを「見る」ことはできません。その出力は正当なものなので、かなり困惑しています。

答えて

36
$(foreach i,1 2 3,$(eval $(call BOZO,$(i)))) 

eval functionそれらを「制定」するために、メイクファイルの構文としての構造を解析するようにしてください伝えます。私はなぜ、Makeがun-evalされた規則に違反しているのかは分からないが、それは学問的なものだ。

+0

D'OH!まあまあ、私はMakefileマクロが初めてです。なぜこれが必要なのか、私はまだ分かりませんが、それがうまくいくので、私はそれを瞑想します。ありがとう! – Joe

30

ベータの答えは正しいですが、私は "私はなぜun-eval'dのルールに反対するのかわかりません"というコメントに対処したいと思いました。

un-evalされたルールがうまくいかない理由は、makefileが最終的に行ベースであり、行がチョップされてからBEFORE変数が展開されるためです。したがって、変数の展開を複数行の結果にすることはできません。たとえ展開に改行が含まれていても、makeは全体を1つの "行"として扱います。makeがforeachループを拡大終了し、結果を解析するときには、基本的にはこれを見て:あなたは、「複数のターゲットパターン」エラーを取得する理由

a1: b c touch a1 a2: b c touch a2 a3: b c touch b3 

です。

evalにより、makeは、展開の結果を、行の途切れなどのmakefile構文の完全なスニペットとして最初から解釈し直すため、複数の行の展開がそこで機能します。

+0

ありがとう、非常に便利です! – Joe

+0

この説明は、私が仕事場で遭遇した非常に複雑なメイクファイルを理解するのに非常に役立ちました。 –

0

after using eval function still i am facing multiple pattern stop issue. I am recursively building target using foreach but i am facing this multiple target issue. while running make file on window 32 bit platform(which run correctly for linux machine)

define BOZO 
$(CWD)/$(1).o:$(CWD).$(1).def 
endef 
$(foreach target,$(basename $(list)),$(eval $(call BOZO,$(target)))) 

$(CWD)/%.def: a.out 
    @echo building [email protected] 
    a.out %.def 

このような何か。あなたはこれを提案することができます...!

+1

このコードをご覧いただきありがとうございます。すぐに役立つかもしれません。適切な説明は、なぜ*これが問題の良い解決策であるかを示すことによってその教育上の価値を大幅に改善し(// meta.stackexchange.com/q/114762)、将来の同様の、しかし、同一ではない質問。説明を追加するためにあなたの答えを[編集]し、どんな制限と前提が適用されるかを示してください。 –

関連する問題