递归 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 字符串和命令中指定它。
我有一个 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 参数,而不是添加对变量的额外依赖。我也希望尽可能少地修改 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 字符串和命令中指定它。