我正在尝试为源代码树设置基于CMake的并行构建,但是当我发出
时$ cmake .
$ make -j2
我明白了:
jobserver unavailable: using -j1. Add '+' to parent make rule
作为警告。有没有人知道是否有可能以某种方式修复它?
答案 0 :(得分:23)
在生成的Makefile中,当调用sub-make时,它需要使用$(MAKE)(不仅仅是'make')或者在行前面加上+。也就是说,规则应如下所示:
mysubdir:
$(MAKE) -C mysubdir
或者像这样:
mysubdir:
+make -C mysubdir
如果你不这样做,那么make会给你那个警告。
我对cmake一无所知,所以也许它生成的Makefile不正确。或者你可能在你的方面做错了什么。
答案 1 :(得分:7)
在我的情况下(使用CMake 3.5.2),琐碎的cd build && cmake .. && make -j5
工作正常。
但是,在通过cmake --build . --target foo
习语构建自定义目标(作为其他目标的依赖关系)时,确实会出现 jobserver unavailable 错误。
像这样:
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开发者在邮件列表上的explained,根本原因在于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
会丢弃作业服务器环境,最终导致单线程编译。
对我来说非常有用的解决方法,如链接电子邮件中所示,是使用 +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
最后,它出现在相应makefile中的buildroot
规则中(CMake生成了一堆),并使GNU Make正常运行并尊重-j
。
希望这有帮助。
答案 2 :(得分:0)
看起来这不是一个cmake问题,而是仅限制。
答案 3 :(得分:-1)
从谷歌搜索看起来你正在使用distcc(例如here)