2017-05-09 5 views
0

は、次のメイクファイルを検討してください。Makefileセカンダリ拡張:エスケープされた関数の実行?

.SECONDEXPANSION: 

%.result: jobs/% $$(call get-job,$$<) 
    echo $^ 

define get-job 
$(shell head -n 1 $(1)) 
$(shell tail -n +2 $(1)) 
endef 

アイデアは/ジョブ中の各ファイルは、前提条件のリストに追加されるべきファイル名のリストが含まれていることです。

私は、既存のファイルから/ XYZジョブをxyz.resultを作成したい場合は、私は次のようなエラーメッセージが出ます:

$ make -n xyz.result 
head: cannot open 'xyz.result' for reading: No such file or directory 
tail: cannot open 'xyz.result' for reading: No such file or directory 
head: cannot open 'xyz.result' for reading: No such file or directory 
tail: cannot open 'xyz.result' for reading: No such file or directory 
make: *** No rule to make target 'xyz.result'. Stop. 

を私は$$<に設定されていないことを認識していますそれは以前のルールの前提条件リストを反映しているからです。私は理解していないと、次のされて
:私の理解で

  • (第2のサブ見出しの下、official docの例のように)、$$<は、空の文字列に評価する必要があります。しかし、それはここの目標値(xyz.result)の値に拡大されているようです。何故ですか?
  • 関数が2回呼び出されたようです(headおよびtail両方の樹皮が2つあります)。前提条件のリストが2回展開されていることを理解しています。しかし、最初の実行では、callはまだエスケープされているので、これは私が期待するものではありません。 $$<がそのように展開し、なぜ私にはわからない

(多分全体的なアプローチは、欠陥がある、と私は最初の場所でのタスクのこの種のMakefileを使用して(AB)ではありません。)

答えて

1

あなたはしかし、代わりに$$*を使用して、構成作業を行うことができます。

%.result: jobs/% $$(strip $$(call get-job,jobs/$$*)) 
     echo $^ 

あなたはcallの結果に埋め込まれた改行をスペースに変換されますようにstrip呼び出しを追加する必要があります。

+0

ありがとうございます!なぜか、私は理解できません。なぜなら、 'ストリップ'と呼ぶと 'ゲット・ジョブ'が2回実行されるのではないかと思いますか?それらの改行はすべての後に 'head'と' tail'に由来します。 – lenz

+0

2回呼び出されません。それは一度呼び出されます。しかし、 'define' ...' endef'に埋め込まれた改行は保持されます。したがって、最初のシェルコマンドの出力と2番目のシェルコマンドの出力には改行があります。あなたは 'define-'を使わずに 'get-job = $(shell head -n 1 $(1))$(shell tail -n +2 $(1))'のように書くことができます。 'strip'呼び出しが必要です。 – MadScientist

+0

私は参照してください。しかし、なぜ頭と尾からそれぞれ2つのエラーメッセージが出るのですか? – lenz

関連する問題