GNU中的递归作业的并行化

时间:2009-11-05 14:46:05

标签: makefile parallel-processing

我正在寻找一种优雅的方式来实现GNU make中的作业并行化。这是我到目前为止所做的一个例子。以连续的方式处理目录dir-1,dir-2和dir-3,这是合乎逻辑的,但不是我的意图:

SUBDIRS=dir-1 dir-2 dir-3

default: all

all:
  @for dir in $(SUBDIRS); do (cd $$dir; $(MAKE)); done

.PHONY: clean

clean:
  @for dir in $(SUBDIRS); do (cd $$dir; $(MAKE) clean); done

有没有办法支持使用“-j”选项并行处理这些目录而不为每个目录指定特定目标?

4 个答案:

答案 0 :(得分:15)

SUBDIRS = a b c

default: all

$(SUBDIRS)::
    $(MAKE) -C $@ $(MAKECMDGOALS)

all clean : $(SUBDIRS)

答案 1 :(得分:5)

这可能不会直接回答你的问题,但除了其他答案提出的建议外,我建议你研究一下非递归制作技巧。这确实是一种优化的并行化构建方式,但是,根据现有的Makefile,可能需要付出很大的努力。非递归make的优点不仅限于简单的并行化:它可以看到完整的依赖图,因此不需要构建太少或太多,这意味着构建时间更快(有时更快)。

一些资源:

答案 2 :(得分:4)

我发现当使用::(双冒号规则)时,如果applib和{{1}之间存在任何依赖关系,我找不到强制顺序的方法}。在阅读了大部分GNU Make手册之后,我提出了以下规则来强制执行依赖关系,同时具有通用的递归make。请注意,即使目录已存在,.PHONY规则也会强制make进入目录。

doc

答案 3 :(得分:3)

dir-1,dir-2和dir-3是相互依赖还是独立?

我有一个类似的结构,但在子目录之间依赖,所以我更喜欢在每个子目录中使用并行构建。你可以通过

获得
## default to four parallel runs
MAKEFLAGS += -j 4  

all:
  @for dir in $(SUBDIRS); do (cd $$dir; $(MAKE) ); done

但另一个技巧是在make手册中阅读SUBDIRS - 您不需要for循环,因为make可以为您展开。尝试像

这样的东西
## default to four parallel runs
MAKEFLAGS += -j 4  

SUBDIRS =    dir-1 dir-2 dir-3

$(SUBDIRS):  #whatever your depends here
             $(MAKE) -C $@