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

Number of parallel build jobs in recursive make call

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

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

这很好用,直到我想 运行 并行生成。在某些系统上它工作正常,但在其他系统上我 运行 进入记录的问题与 -j 标志时 passing options to a sub-make:

If your operating system doesn’t support the above communication, then ‘-j 1’ is always put into MAKEFLAGS instead of the value you specified. This is because if the ‘-j’ option were passed down to sub-makes, you would get many more jobs running in parallel than you asked for.

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

有没有办法强制一个 sub-make 使用多个作业?或者,一种让 -l 标志真正完成某些事情的方法?

我认为我可以使用 -@$(MAKE) $(JOBS) real_target 等 makefile 修改并像 make JOBS="-j4" main_target.

那样调用 make 来做到这一点

但是,我更愿意只使用标准的 make 参数,而不是添加对变量的额外依赖。我也希望尽可能少地修改 makefile。

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

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

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

问题是,无论出于何种原因,我的 make 不支持作业服务器,因此它不会在 $(MAKEFLAGS) 变量中传递 -j 标志。由于将 make 升级到 确实 传递标志的版本不是一个选项,因此解决方案是在其他地方传递 -j 标志。就和一样,可以用同样的方式传递-j标志:

make MAKE="make -j4" main_target

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