13

make -j N每当我make从终端调用时,我希望我的 CMake 项目由 构建。我不想-j每次都手动设置选项。

为此,我将CMAKE_MAKE_PROGRAM变量设置为特定的命令行。我使用这个ProcessorCount()函数,它给出了并行执行构建的处理器的数量。

当我这样做时make,我看不到任何加速。但是,如果我这样做make -j N,那么它的构建速度肯定会更快。

你能帮我解决这个问题吗?(我正在 Linux 上开发这个。)

这是我使用的代码片段CMakeList.txt

include(ProcessorCount)
ProcessorCount(N)
message("number of processors: "  ${N})
if(NOT N EQUAL 0)
  set(CTEST_BUILD_FLAGS -j${N})
  set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N})
  set(CMAKE_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM} -j ${N}")      
endif()
message("cmake make program" ${CMAKE_MAKE_PROGRAM})

非常感谢。

4

5 回答 5

10

如果您想加快构建速度,您可以并行运行多个 make 进程,但不能运行 cmake。要使用预定义数量的并行进程执行每个构建,您可以在MAKEFLAGS中定义它。

在您的环境脚本中设置 MAKEFLAGS,例如 ~/.bashrc ,如您所愿:

export MAKEFLAGS=-j8

在 Linux 上,以下将 MAKEFLAGS 设置为 CPU 的数量 - 1:(在构建时为其他任务保留一个 CPU 空闲)并且在具有动态资源的环境中很有用,例如 VMware:

export MAKEFLAGS=-j$(($(grep -c "^processor" /proc/cpuinfo) - 1))
于 2017-01-17T07:13:55.183 回答
4

通过设置要影响构建过程的CMAKE_MAKE_PROGRAM变量。但:

  1. 此变量仅影响构建 via cmake --build,而不影响本机工具( make) 调用:

    CMAKE_MAKE_PROGRAM变量设置为供项目代码使用。--buildcmake(1)和 ctest(1)工具也使用该值--build-and-test来启动本机构建过程。

  2. 这个变量应该是一个CACHE d 变量。类似make的生成器以这种方式使用它:

    这些生成器将 CMAKE_MAKE_PROGRAM 存储在 CMake 缓存中,以便用户可以对其进行编辑。

    也就是说,您需要使用

    set(CMAKE_MAKE_PROGRAM <program> CACHE PATH "Path to build tool" FORCE)
    
  3. 这个变量应该引用可执行文件本身,而不是带有参数的程序:

    该值可能是可执行文件的完整路径,或者如果预期位于 PATH 中,则只是工具名称。

    也就是说,值“make -j 2”不能用于该变量(将参数拆分为列表

    set(CMAKE_MAKE_PROGRAM make -j 2 CACHE PATH "Path to build tool" FORCE)
    

    也无济于事)。

总之,您可以通过将CMAKE_MAKE_PROGRAM变量设置为脚本cmake --build来重新定义调用的行为,该脚本使用并行选项进行调用。但是你可能不会影响直接调用的行为。makemake

于 2017-01-17T07:43:43.407 回答
3

您可以使用此命令设置环境变量 MAKEFLAGS

export MAKEFLAGS=-j$(nproc)
于 2017-11-02T13:11:32.797 回答
0

我的解决方案是有一个运行 make 的小脚本,其中包括各种其他功能,而不仅仅是 CPU 的数量。

我调用了我的脚本mk,然后我做了一个,所以我可以在我的项目的根目录中chmod 755 mk运行它。./mk我还有一些标志可以用一个简单的命令行运行各种东西。例如,在处理代码时遇到很多错误,我喜欢将输出通过管道传输到less. 我可以做到这一点,./mk -l而不必重新输入所有重型 Unix 的东西......

如您所见,我在几个有意义的地方都有 -j4。对于该-l选项,我不想要它,因为在这种情况下,它最终会导致同时打印多个错误(我之前尝试过!)

#!/bin/sh -e
#
# Execute make

case "$1" in
"-l")
    make -C ../BUILD/Debug 2>&1 | less -R
    ;;

"-r")
    make -j4 -C ../BUILD/Release
    ;;

"-d")
    rm -rf ../BUILD/Debug/doc/lpp-doc-?.*.tar.gz \
           ../BUILD/Debug/doc/lpp-doc-?.*
    make -C ../BUILD/Debug
    ;;

"-t")
    make -C ../BUILD/Debug
    ../BUILD/Debug/src/lpp tests/suite/syntax-print.logo
    g++ -std=c++14 -I rt l.cpp rt/*.cpp
    ;;

*)
    make -j4 -C ../BUILD/Debug
    ;;

esac

# From the https://github.com/m2osw/lpp project

使用 CMake,除非像 Tsyvarev 提到的那样,您创建自己的脚本,否则它将无法工作。但我个人认为从你的make script调用 make 是不明智的。另外,它可能会破坏一个不会期望那个奇怪脚本的构建过程。最后,正如我所提到的,我的脚本允许我根据情况改变选项。

于 2019-06-11T08:15:28.923 回答
0

我通常在 linux 中使用 alias 来设置cm等于cmake .. && make -j12. 或者写一个shell来指定make和clean进度...

alias cm='cmake .. && make -j12'

然后cm在单个命令中使用 make 。

于 2021-10-29T03:34:46.013 回答