递归调用中的并行构建作业数

时间:2015-03-11 18:31:25

标签: makefile gnu-make

我有一个makefile,它将真正的构建包装在一个递归调用中,以便在构建周围获取和释放许可证,无论构建是否成功。例如:

.PHONY main_target
main_target:
    @license_grab &
    @sleep 2
    -@$(MAKE) real_target
    @license_release

这很好用,直到我想并行运行make。在某些系统上它工作正常,但在其他系统上,当passing options to a sub-make时,我遇到了带-j标志的文档问题:

  

如果您的操作系统不支持上述通信,那么   '-j 1'总是放入MAKEFLAGS而不是你的值   指定。这是因为如果将'-j'选项传递给   sub-make,你会获得比你更多的并行运行的工作   要求。

因为我只有一次递归调用,所以我真的希望将-j标志不变地传递给子make。我不想将-j标志(带有数字)硬编码到makefile中,因为makefile在具有不同处理器数量的多台机器上运行。我不想在没有限制的情况下使用-j,因为它会立即启动一堆进程而不是等待作业完成。我在构建时尝试使用-l标志,但我发现限制不会立即应用,可能是因为limits don't apply until make can start sampling

有没有办法强制子制作使用多个作业?或者,一种使-l标志真正实现的方法是什么?

我认为我可以使用makefile修改,例如使用-@$(MAKE) $(JOBS) real_target,并调用make make JOBS="-j4" main_target

但是,我更喜欢使用标准的make参数,而不是在变量上添加额外的依赖项。我也希望尽可能少地修改makefile。

2 个答案:

答案 0 :(得分:4)

无法在不支持jobserver功能的系统上更改此行为。像JOBS变量这样的东西是我能想到的唯一方法。

我要指出一些事情:首先,我假设当你说其他系统你指的是Windows系统时:这是我唯一常用的平台I'我知道哪些不支持作业服务器。如果是这样,请注意,从GNU make 4.0版开始,在Windows上实现了jobserver支持。所以另一种选择是升级到更新版本的GNU make。

其次,-l选项的问题至少部分在GNU make 3.81版中得到解决,其中引入了额外的算法来根据调用的作业数量人为地调整负载平均值。在此之后,您不应该再使用make版本来查看此问题。

答案 1 :(得分:1)

问题在于,无论出于何种原因,我的make都不支持作业服务器,因此它不会在-j变量中传递$(MAKEFLAGS)标志。由于升级到 传递标志的版本不是一个选项,因此解决方案是将-j标志传递到其他位置。就像the $(MAKE) variable can be abused to pass the -f flag一样,它可以以相同的方式用于传递-j标志:

make MAKE="make -j4" main_target

这将使用一个作业启动main_target构建,但在子制作过程中调用make 4个作业。显然,如果你需要一个特殊的制作工具(normal purpose of $(MAKE),那么你需要在MAKE字符串和命令中指定它。