从CMake设置'make'到默认使用'-j'选项

时间:2017-01-16 20:51:13

标签: cmake parallel-builds

每当我从终端拨打make -j N时,我希望我的CMake项目由make构建。我不想每次都手动设置-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})

非常感谢。

5 个答案:

答案 0 :(得分:6)

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

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

export MAKEFLAGS=-j8

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

export MAKEFLAGS=-j$(($(grep -c ^processor /proc/cpuinfo) - 0))

答案 1 :(得分:2)

通过设置您希望影响构建过程的CMAKE_MAKE_PROGRAM变量。但是:

  1. 此变量仅影响cmake --build上的构建,而不影响原生工具make)调用:

      

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

  2. 此变量应为 CACHE 1。它通过 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)
    

    也不会有帮助。)

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

答案 2 :(得分:2)

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

export MAKEFLAGS=-j$(nproc)

答案 3 :(得分:0)

此方法可以用于调用多个函数吗?像function1,2,3并行而非顺序,任何其他想法都赞赏。

示例:

 if(FLAG1)
#some variables/options settings
    function1(${OPTIONS})
    function2(${OPTIONS})
    function3(${OPTIONS})
     ....
endif()

function(fucntion1)
#some variables/options parsing and passed to command.
      execute_process(COMMAND COMMAND1
                    WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
                    RESULT_VARIABLE res
                    TIMEOUT 60)
endfunction()
function(fucntion2)
#some variables/options parsing and passed to command.
      execute_process(COMMAND COMMAND2
                    WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
                    RESULT_VARIABLE res
                    TIMEOUT 60)
endfunction()

答案 4 :(得分: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脚本调用make并不明智。另外,它可能会破坏不会期望 strange script 的构建过程。最后,如上所述,我的脚本允许我根据情况改变选项。