我正在尝试为我的源代码树设置一个基于 CMake 的并行构建,但是当我发出
$ cmake .
$ make -j2
我得到:
jobserver unavailable: using -j1. Add '+' to parent make rule
作为警告。有没有人知道是否有可能以某种方式修复它?
我正在尝试为我的源代码树设置一个基于 CMake 的并行构建,但是当我发出
$ cmake .
$ make -j2
我得到:
jobserver unavailable: using -j1. Add '+' to parent make rule
作为警告。有没有人知道是否有可能以某种方式修复它?
在生成的 Makefile 中,当调用子 make 时,它需要使用 $(MAKE)(不仅仅是 'make')或者在该行之前加上一个 +。也就是说,规则应如下所示:
mysubdir:
$(MAKE) -C mysubdir
或像这样:
mysubdir:
+make -C mysubdir
如果您不使用这两种方式之一,make 会给您这个警告。
我对cmake一无所知,所以它可能会生成不正确的Makefile。或者,也许你最终做错了什么。
在我的情况下(使用 CMake 3.5.2),微不足道的cd build && cmake .. && make -j5
工作就好了。
但是,当通过成语构建自定义目标(作为其他目标的依赖项)时,我确实得到了作业服务器不可用错误。cmake --build . --target foo
像这样:
add_custom_target(buildroot
COMMAND ${CMAKE_COMMAND} --build . --target install
COMMENT "Populating buildroot..."
)
add_dependencies(deb buildroot)
add_dependencies(rpm buildroot) #... etc
— 这样用户就可以make deb
并且它只是工作。如果需要,CMake 将重新生成 makefile,运行编译,install
一切都与 完全相同make install
,然后运行我的自定义脚本以将填充的 buildroot 打包成我需要的任何形状或形式。
果然,我很想make -j15 deb
——但那失败了。
现在,正如CMake 开发人员在邮件列表中所解释的那样,令人惊讶的是(或不是)根本原因在于 GNU Make;有一个解决方法。
根本原因是它make
不会将其作业服务器环境传递给它认为不是的子进程make
。
为了说明,这里有一个进程树 ( ps -A f
) 分支:
…
\_ bash
\_ make -j15 deb
\_ make -f CMakeFiles/Makefile2 deb
\_ make -f CMakeFiles/buildroot.dir/build.make CMakeFiles/buildroot.dir/build
\_ /usr/bin/cmake --build . --target install ⦿
\_ /usr/bin/gmake install
…
在⦿点,make
丢弃jobserver环境,最终导致单线程编译。
正如链接的电子邮件中所提供的那样,对我来说非常有用的解决方法是在所有自定义命令前加上+env
. 像这样:
add_custom_target(buildroot
#-- this ↓↓↓ here -- https://stackoverflow.com/a/41268443/531179
COMMAND +env ${CMAKE_COMMAND} --build . --target install
COMMENT "Populating buildroot..."
)
add_dependencies(deb buildroot)
add_dependencies(rpm buildroot) #... etc
最后,这出现在buildroot
适当的 makefile 的规则中(CMake 会生成一堆),并导致 GNU Make 行为正确并尊重-j
.
希望这可以帮助。
看起来这不是 cmake 问题,而只是 make。
只是从谷歌搜索看起来你正在使用 distcc (例如这里)