2013-07-24 171 views
0

這是我的Makefile中的兩個目標。Makefile中的路徑依賴關係

.SECONDARY: 
exp-%.ans: 
    echo $* > eval/[email protected] 

%.scores: %.ans 
    cat eval/$< > eval/[email protected] 

當我寫make -n exp-40.scores輸出爲:

echo 40 > eval/exp-40.ans 
cat eval/exp-40.ans > eval/exp-40.scores 

這是很好的,除了一兩件事。它不知道依賴已經被保留。如果我創建eval/exp-40.scores(第一次),那麼我希望make會說它已經在那裏,如果我運行相同的命令。所以,我試圖改變我的Makefile是這樣的:

.SECONDARY: 
exp-%.ans: 
    echo $* > eval/[email protected] 

%.scores: eval/%.ans 
    cat eval/$< > [email protected] 

當我再次寫make -n exp-40.scores輸出將是:

echo eval/40 > eval/eval/exp-40.ans 
cat eval/eval/exp-40.ans > exp-40.scores 

這是完全錯誤的,因爲我的參數應該是40不EVAL/40。

我該如何實現這兩個世界中最好的?也就是說,我想在eval /文件夾中創建* .scores。我也想做檢查文件是否已經存在或沒有。然後使該按照該文件存在進行。

謝謝。

回答

2

make的核心規則之一就是你需要建立你的規則告訴你的目標。像foo : bar這樣的規則告訴如果它運行該配方,配方將創建或更新名爲foo的文件。如果配方創建或更新一個名爲biz/foo的文件,那麼您的makefile是錯誤的,並且不起作用。

Make始終將它希望創建的配方放入[email protected]自動變量中。你的配方應該創建或更新[email protected][email protected]。不是別的。

你的情況

所以,你需要寫:

eval/exp-%.ans: 
     echo $* > [email protected] 

eval/%.scores: eval/%.ans 
     cat $< > [email protected] 

如果你想能夠運行make exp-40.scores並有它實際上創造eval/exp-40.scores,那麼你就可以添加一條規則是這樣的:

%.scores: eval/%.scores ; @: 

(你必須提供一些模式規則的配方,他們不能有一個空的配方;上面的一個沒有做什麼)。

+0

非常感謝您在開始時的回答和澄清。我需要一個包含Makefile性質的教程。你知道這件事嗎?網上有很多簡短的教程,其目的通常是提供一些技巧和竅門來做快速和骯髒的事情。我聽說(我不確定)make的文檔不好,存在很多bug。有一本O'Reilly的書(http://shop.oreilly.com/product/9780596006105.do),但它的評價是平均的。 – Thorn

+0

如果你不好意思,我想再問兩個問題。 (1)如果我刪除.SECONDARY,則刪除我的中間文件,這對我來說非常重要。我閱讀(章節爲.SECONDARY,.INTERMEDIATE和.PRECIOUS)手冊,但我不明白哪一個適合這種情況。 (2)並且.SECONDARY是否會影響下面的所有目標? – Thorn

+2

我認爲GNU make手冊不錯。我不知道它有任何錯誤。但是請注意,GNU網站上的手冊版本記錄了GNU make的最新穩定版本。如果您使用的是舊版本,那麼手冊中的某些語句將不適合您的版本。您應該閱讀與您使用的GNU版本相同的手冊版本,以避免混淆。本手冊與GNU make一起打包,因此您應該能夠從您製作軟件包的相同位置爲您的版本獲取正確的文檔。 – MadScientist