2012-11-29 132 views
7

我想在多個目錄中執行一個任務,但到目前爲止還沒有找到「類似makefile」的解決方案。我知道這是一個經常被問到的問題,我知道如何解決子makfiles等,但我正在尋找更簡單的東西。遍歷Makefile中的目錄列表

而不是做

copy: 
    cd module1 && mkdir foo 
    cd module2 && mkdir foo 
    cd module3 && mkdir foo 

的,我想有這樣的事情

directories = module1 module2 module3 

copy: $(directories) 
    cd $< && mkdir foo 

,但不起作用,因爲receipe被稱爲僅第一次目錄。我想出了這種解決方案,但可能不符合Makefiles的風格:

directories = module1 module2 module3 

copy: 
    for d in $(directories); do cd $$d && mkdir foo && cd ..; done 

我該如何做得更好?

回答

6

有許多這樣做的方法。

你可以做什麼安德魯表明沒有硬編碼的前綴:

directories = module1 module2 module2 

%/foo: ; mkdir -p -- "[email protected]" 

copy: $(addsuffix /foo,$(directories)) 

這給

$ make -n copy 
mkdir -p -- "module1/foo" 
mkdir -p -- "module2/foo" 
mkdir -p -- "module3/foo" 

您也可以從生成文件生成copy目標:

directories = module1 module2 module2 

define copy-target 
    copy:: ; cd $1 && mkdir foo 
endef 

$(foreach dir,$(directories),$(eval $(call copy-target,$(dir)))) 

這給出:

$ make -n copy 
cd module1 && mkdir foo 
cd module2 && mkdir foo 
cd module3 && mkdir foo 

你也可以生成命令,而不是目標:

directories = module1 module2 module2 

copy: ; $(foreach dir,$(directories),(cd $(dir) && mkdir foo) &&) : 

導致

$ make -n copy 
(cd module1 && mkdir foo) && (cd module2 && mkdir foo) && (cd module3 && mkdir foo) && : 
+0

謝謝,這是有效的。我選擇瞭解決方案2(從makefile生成'copy'目標),因爲它沒有綁定到'mkdir'的情況。不幸的是,它與使用shell-for-loop沒有多大區別,但這並不重要。 – Robert

2

在Makefiles中,無論何時想要創建文件,都需要制定一個規則,將文件的名稱作爲目標,然後給該命令創建目標文件。

copy: module1/foo module2/foo module3/foo 

module%/foo: 
     mkdir [email protected] 

如果您想參數,一個位,以避免重複,你也可以編寫類似

MODULE_NUMBERS = 1 2 3 

copy: ${MODULE_NUMBERS:%=module%/foo} 

module%/foo: 
     mkdir [email protected] 
+0

感謝。不幸的是,我無法應用您的解決方案,因爲我無法使用通配符(在您的示例中爲「module%」)解決相關目錄,因爲我有許多目錄具有相同的前綴並且想要使用變量(在我的示例中爲「目錄」 )只選擇其中一些。順便說一句:我只是使用「mkdir」作爲示例命令(實際上,我不想創建目錄,而是將每個目錄中的文件上傳到服務器),因此無論手頭的任務如何,解決方案都應該可以工作。 – Robert