我正在使用递归 Makefile 运行 make (GNU Make 3.82)。
我正在运行make -j2
以仅并行生成 2 个进程。
内部 Makefile 用 $(MAKE) 调用。
但是,看起来内部 Makefile(由主 Makefile 启动)无限生成进程,就好像它是给定的-j
,而不是-j2
.
为了验证这一点,我转储了孩子“make”的环境变量:
# pgrep -a make
17218 make -j2
17227 make -C obj_dir/ -f Vf1_package.mk ...
# strings /proc/17227/environ
...
MAKEFLAGS= --jobserver-fds=3,4 -j
...
MAKEFLAGS
没有在任何地方显式设置,并且-j
只在命令行中提供,并且不会出现在 makefile 的任何地方。因此,似乎“make”本身决定在为孩子“make”-j
编写时从论点中去除“2”。MAKEFLAGS
知道什么可能导致“make”设置MAKEFLAGS
为-j
而不是-j2
?
更新 1
我已经确定了问题,但我仍然不明白为什么会发生以及如何解决。
问题是当子制作在SCL上下文下运行时,作业服务器无法正常工作。
这是必需的,因为我需要子制作才能使用特定的 gcc 工具链。
SCL = scl enable devtoolset-8
...
sub_make:
$(SCL) "$(MAKE) -C $(SUB_MAKE_DIR) ... "
像这样运行时,子制作会产生无限数量的作业。删除 SCL 后,它会按预期工作。
- 为什么 SCL 会干扰 make 的作业服务器?
- 我该如何解决这个问题?我知道我可以在运行外部 Makefile 之前启用 SCL,但我想从 Makefile 中控制工具集。
更新 2
这似乎与SCL更改PATH
环境变量的事实有关。在 newPATH
上,“make”是较新的(“GNU Make 4.2.1”)。
因此,如果顶级 make 正在运行旧的 GNU Make 3.82 并且子 make 正在运行更新的 4.2.1 make,那么 make 作业服务器似乎会失败,也许这些版本之间在 make 与子 make 通信的方式上发生了一些变化。