Makefile 限制子生成中的并发

Makefile 限制子生成中的并发,makefile,gnu-make,parallel-builds,Makefile,Gnu Make,Parallel Builds,对于分布在多个子目录上的项目,我们使用gnumake进行构建。开发人员可以使用-j标志并行化构建任务,并选择适合其机器硬件的数字 然而,我们使用的第三方库的makefile并行化并不安全——它们显然依赖于目标的隐式顺序,而不是所有依赖目标之间的显式依赖规则 由于我不想修复第三方Makefiles,我们目前使用显式的-j1参数调用它们的Makefiles,以将构建该库的作业数限制为1。规则如下所示: third_party_lib: $(MAKE) -j 1 -C $@ 这可以根据需要工

对于分布在多个子目录上的项目,我们使用gnumake进行构建。开发人员可以使用
-j
标志并行化构建任务,并选择适合其机器硬件的数字

然而,我们使用的第三方库的makefile并行化并不安全——它们显然依赖于目标的隐式顺序,而不是所有依赖目标之间的显式依赖规则

由于我不想修复第三方Makefiles,我们目前使用显式的
-j1
参数调用它们的Makefiles,以将构建该库的作业数限制为1。规则如下所示:

third_party_lib:
    $(MAKE) -j 1 -C $@
这可以根据需要工作,但是,make会为此发出警告:

make[1]: warning: -jN forced in submake: disabling jobserver mode.

这让我想问,是否有更好的方法限制一个子生成中的并行作业数。

您可以将
.NOTPARALLEL:
特殊目标添加到不应并行化的生成文件中

如果不想修改这些makefile,可以使用命令行上的
--eval
选项(注意
--eval
是在GNU make 3.82中添加的):


谢谢你的建议。文档中声明“任何递归调用的make命令仍将并行运行recipes…”,因此我可能必须修改make变量,使其包含--eval才能工作。将在我们的詹金斯和当地进行一段时间的测试,然后回到这个答案。你是说这个建议在你尝试的时候不起作用吗?我不确定我是否理解您对文档的引用。递归make将启动,父make将配置它并行运行。然后,递归make将运行
--eval
,而
.NOTPARALLEL:
特殊目标将禁用并行性,就像您编辑递归make的makefile以包含该值一样。您肯定不想修改
MAKE
变量的内容。我指的是“任何递归调用的MAKE命令仍将并行运行配方”,我认为这意味着来自第三方库/Makefile的任务一次只运行一个,但其子目录中Makefiles中的任务可以再次并行运行。是的,第一次测试成功了,但是并发错误只是偶尔出现,因此,这需要更多的测试运行来确保。这意味着
.NOTPARALLEL:
选项只对它出现的makefile生效(或者在本例中,make的实例被赋予了
--eval.NOTPARALLEL:
参数)。因此,如果
third_party_lib
makefile本身是递归的,那么是的,您确实需要确保所有递归版本也获得该设置。我不知道重置
MAKE
变量是否有效。您始终可以创建一个小shell脚本
npmake
或使用此选项生成的
exec
,然后为
第三方库运行该脚本。
third_party_lib:
        $(MAKE) --eval .NOTPARALLEL: -C $@