16

我正在尝试为我的源代码树设置一个基于 CMake 的并行构建,但是当我发出

$ cmake .
$ make -j2

我得到:

jobserver unavailable: using -j1.  Add '+' to parent make rule

作为警告。有没有人知道是否有可能以某种方式修复它?

4

4 回答 4

24

在生成的 Makefile 中,当调用子 make 时,它​​需要使用 $(MAKE)(不仅仅是 'make')或者在该行之前加上一个 +。也就是说,规则应如下所示:

mysubdir:
    $(MAKE) -C mysubdir

或像这样:

mysubdir:
    +make -C mysubdir

如果您不使用这两种方式之一,make 会给您这个警告。

我对cmake一无所知,所以它可能会生成不正确的Makefile。或者,也许你最终做错了什么。

于 2010-11-21T15:18:56.903 回答
9

在我的情况下(使用 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.

希望这可以帮助。

于 2016-12-21T17:20:26.217 回答
0

看起来这不是 cmake 问题,而只是 make。

于 2010-08-20T13:29:11.800 回答
-1

只是从谷歌搜索看起来你正在使用 distcc (例如这里

于 2010-06-01T20:59:06.637 回答