2015-04-16 24 views
1

我想用一個Makefile寫一個文件static/config.js以下方式:如何使Makefile注意到新文件的存在?

  • 如果js/config_local.js存在,將它複製到static/config.js
  • 否則,複製js/config.js(它總是存在的話)static/config.js

到目前爲止,我看起來像這樣:

# If there's a config_local.js file, use that, otherwise use config.js 
ifneq ($(wildcard js/config_local.js),) 
config_file = js/config_local.js 
else 
config_file = js/config.js 
endif 

static/config.js: js/config.js js/config_local.js 
    cp $(config_file) static/config.js 

js/config_local.js: 

clean: 
    rm -f static/* 

這主要是工作,除了如果沒有js/config_local.js文件,我運行make,然後我創建一個js/config_local.js文件並再次運行make,它認爲它不需要做任何事情。我猜這是因爲Makefile中有空的js/config_local.js目標,但是如果我刪除它,那麼如果js/config_local.js文件不存在,它就無法生成。

我還試圖消除空js/config_local.js目標和static/config.js目標的依賴關係設置爲js/*.js,但是這並沒有注意到它需要後,我創建js/config_local.js文件做一些同樣的問題。

+0

也使用'$(config_file)'作爲prereq。但是,如果'static/config.js'比'js/config_local.js'更新,那麼這對你的示例場景沒有幫助,因爲這就是make的作用(避免了它不需要再做的工作)。 –

+0

另外'config_file = $(word 1,$(通配符js/config_local.js js/config.js))'會爲您提供一行中存在的第一個。 –

+0

@Etan - 將'$(config_file)'添加到'static/config.js'的依賴關係似乎沒有改變任何東西。 – Avril

回答

2

檢查文件時間,而不是內容。 .PHONY將始終強制執行操作。缺點是它總是複製。使用-p開關保存文件時間。

.PHONY: static/config.js 
static/config.js : $(firstword $(wildcard js/config_local.js js/config.js)) 
cp -p $< [email protected] 
+0

如果'static/config.js'是任何其他目標的先決條件,'.PHONY'是一個糟糕的選擇。在這種情況下,FORCE規則更好。 –

+0

這似乎工作,謝謝! @Etan - 在我的情況下,'static/config.js'目標是另一個目標的先決條件......你能解釋爲什麼會使'.PHONY'成爲不好的選擇嗎? – Avril

+0

從[手冊](http://www.gnu.org/software/make/manual/make.html#Phony-Targets):「虛假目標不應該是實際目標文件的先決條件;如果它是,它的配方將在每次更新該文件時運行。「實質上,'.PHONY'-ness會滲透到鏈中的所有內容中,即使文件完全沒有改變(或者比其他文件更早),您也會重新運行比預期更多的配方。這就是說,如果你正在做的副本,你可能*想*其他目標也可能運行(可能),這只是使事情複雜化。 –