2012-11-29 99 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