我正在寻找一种优雅的方式来实现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”选项并行处理这些目录而不为每个目录指定特定目标?
答案 0 :(得分:15)
SUBDIRS = a b c
default: all
$(SUBDIRS)::
$(MAKE) -C $@ $(MAKECMDGOALS)
all clean : $(SUBDIRS)
答案 1 :(得分:5)
这可能不会直接回答你的问题,但除了其他答案提出的建议外,我建议你研究一下非递归制作技巧。这确实是一种优化的并行化构建方式,但是,根据现有的Makefile,可能需要付出很大的努力。非递归make的优点不仅限于简单的并行化:它可以看到完整的依赖图,因此不需要构建太少或太多,这意味着构建时间更快(有时更快)。
一些资源:
答案 2 :(得分:4)
我发现当使用::(双冒号规则)时,如果app
,lib
和{{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 $@