2017-05-09 30 views
0

考慮下面的Makefile:Makefile二次擴展:執行轉義函數?

.SECONDEXPANSION: 

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

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

的想法是,在工作/每個文件都包含一個文件名列表,它應該被追加到列表的先決條件。

但是,如果我想從現有的文件創建xyz.result工作/ XYZ,我收到以下錯誤信息:

$ 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. 

我知道$$<未設置爲我想要什麼,因爲它反映了先前規則的先決條件列表。
什麼我不明白的是:

  • 在我的理解,$$<應該評估爲空字符串(如在official doc的例子中,第二子標題下)。但是,它似乎擴大到了目標值(xyz.result)。這是爲什麼?
  • 看起來get-job函數被調用了兩次(headtail都是兩次)。我瞭解,先決條件列表已擴展兩次。但在第一輪中,call仍然逃脫,所以這不是我所期望的。

(也許整個方法是有缺陷的,我不應該是(AB)使用的Makefile這樣的任務擺在首位。)

回答

1

我不知道爲什麼$$<擴大了辦法。

您可以通過使用$$*代替,雖然讓你的配置工作:

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

您需要添加strip呼叫使嵌入call結果的新行會變成空間。

+0

謝謝,它的作品!我不明白爲什麼,但是 - 你是否知道爲什麼不調用'strip'會導致'get-job'被執行兩次?這些換行符始終來自'head'和'tail',畢竟... – lenz

+0

它不會被調用兩次。它被調用一次。但是,嵌入在'define' ...'endef'中的換行符被保留。所以在第一個shell命令的輸出和第二個shell命令的輸出之間有一個換行符。你可以這樣寫:'get-job = $(shell head -n 1 $(1))$(shell tail -n +2 $(1))''而不使用'define',那麼你不會需要'strip'調用。 – MadScientist

+0

我明白了。但是爲什麼我會從'head'和'tail'得到兩條錯誤消息? – lenz