如何在CMake中配置可移植并行构建?

如何在CMake中配置可移植并行构建?,cmake,parallel-builds,Cmake,Parallel Builds,无论使用哪种构建工具,都可以进行并行构建吗 在Unix下,我们可以添加make-jN,其中N是线程数,在Windows下,我添加了CXX\u标志/MP”,然后在Visual Studio中使用它来并行构建…(?)我如何使我的版本在运行CMAKE时不总是扩展CMAKE\u make\u程序 什么是一般解决方案 我想到了这个: # Add some multithreaded build support MARK_AS_ADVANCED(MULTITHREADED_BUILD) set(MULTIT

无论使用哪种构建工具,都可以进行并行构建吗

在Unix下,我们可以添加
make-jN
,其中N是线程数,在Windows下,我添加了
CXX\u标志/MP”
,然后在Visual Studio中使用它来并行构建…(?)我如何使我的版本在运行CMAKE时不总是扩展
CMAKE\u make\u程序

什么是一般解决方案

我想到了这个:

# Add some multithreaded build support
MARK_AS_ADVANCED(MULTITHREADED_BUILD)
set(MULTITHREADED_BUILD 12 CACHE STRING "How many threads are used to build the project")
if(MULTITHREADED_BUILD)
    if(${CMAKE_GENERATOR} MATCHES "Unix Makefiles")
            message(STATUS ${CMAKE_BUILD_TOOL})
            set(CMAKE_MAKE_PROGRAM "${CMAKE_MAKE_PROGRAM} -j${MULTITHREADED_BUILD}")
            message(STATUS "Added arguments to CMAKE_BUILD_TOOL: ${CMAKE_MAKE_PROGRAM}")
    elseif(MSVC)
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
      message(STATUS "Added parallel build arguments to CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
    endif()
endif()

你不能跨平台这么做。-jN选项是要生成的参数,而不是生成的Makefile的一部分。但是,您可以让CMake生成一个Bash脚本,该脚本使用-jN为您的项目运行make(脚本在其中查找您拥有的内核数)。

如果您有CMake v2.8.8或更高版本,您可以使用以下替代方法:

如您所见,无需使用
CMAKE\u MAKE\u程序
,默认情况下,构建是并行运行的,根据可用的CPU内核优化作业数量

Ninja基于低级JSON配置,以加快启动阶段。因此,它的JSON配置不容易手工编写,我总是使用高级工具/IDE生成:

  • (2012年)
  • (2012年)
  • (2013年)
  • 关于Linux(2013)
  • 。。。请参阅第页的忍者配置生成器

作为C++的构建通常需要大量内存,计算机必须提供与CPU核数相同的内存。


正如所指出的,CMake(2018)有一个
CMake--build-j
来限制构建到
内核(作业),从而限制内存消耗(另请参见)。如果使用较旧的CMake版本,仍然可以使用
CMake--build--j
。选项
--
告诉CMake将其余部分直接传递给底层构建器工具,这里是Ninja。

我已经决定为基于
Unix Makefiles
的生成器编写一个
parallelmake.sh
脚本。这是在这里完成的:

以及CMake文件中的相关部分:


使用CMake 3.12,这是可能的。从:

cmake(1)
构建项目(
cmake--Build
)获得了
--parallel[]
-j[]
选项来指定并行构建级别。它们映射到本机生成工具的相应选项

,您还可以设置环境变量
CMAKE\u BUILD\u PARALLEL\u LEVEL

链接到CMake的文档:


现在,使用cmake并行构建非常简单。您可以在使用“cmake--build”时添加“-j jobs_number”。例如:

cmake --build . -j 24
更多详细信息请参见CMAKE手册:

--parallel[],-j[]生成时要使用的最大并发进程数。如果省略了本机构建 使用工具的默认编号

CMAKE_BUILD_PARALLEL_LEVEL环境变量(如果设置)指定 未提供此选项时的默认并行级别

一些本机构建工具总是并行构建。使用 值1可用于限制单个作业


不确定能不能做到,反正也别认为这是个好主意。CMake描述了项目是如何构建的,make是如何完成它的工作的,这与CMake是不同的级别。执行您的方法时,只需将
-dmultipthreaded\u build=12
添加到CMake的命令行中。并删除
集合(多线程构建…
在我的Eclipse CDT案例中出现错误:“/usr/bin/make-j8”所有无法运行程序“/usr/bin/make-j8”:未知原因错误:程序“/usr/bin/make-j8”未在路径中找到我的CMake/Eclipse CDT错误是由于CMake\u make\u程序错误:因为这篇文章有点旧,Cuffe>=3.12.0的用户应该考虑VisualStudio的@ USR12345 67:<代码> MSBube YouTyj.SLN/MCPCPUnt:N< /Calp> @ JangDavy:您甚至可以通过调用Cuth.Cuff-Buff-Bug使用CMASE构建工具传递这个参数。maxcpucount:8
因为CMake会将“空的”
--
后面的所有参数传递给生成工具。@RolandSarrazin yep,我当前的脚本是
CMake--build--目标安装--config发行版--/m
,它似乎可以在所有内核上运行。幸亏我也建议不要指定确切的数字,在这种情况下MSBuw会考虑构建必须在所有可用的内核上执行,但不超过现有的。从3.12开始,CMake提供了相应的标志。查看我的答案。您还可以设置环境变量
CMAKE_BUILD_PARALLEL_LEVEL
什么是“它们映射到本机构建工具的相应选项”的确切含义?例如,在使用CMake 3.16.4和Ninja 1.10.0时,它似乎不会自动为MSVC设置
/MP
标志。因此,对于真正的/完全并行构建,似乎仍然没有可用的跨平台解决方案。对于CMake 3.12,最好使用官方方式。关于最后一句话:您可以限制使用
-j N
选项的内核数量,这就是所使用的内存量。感谢在CMake 3.12之前的Ruslan,您可以将此选项传递给忍者-可以像在第一个代码片段中一样直接运行它,或者在CMake--build之后追加
--jN
(即使在CMake 2.8.0中,
--build
的这个
--
功能也存在)。谢谢@Ruslan
mkdir build
cd    build
cmake -G Ninja ..
cmake --build .    # Parallel build using Ninja
# Add some multithreaded build support =====================================================================================================
MARK_AS_ADVANCED(MULTITHREADED_BUILD)
SET(MULTITHREADED_BUILD ON CACHE BOOL "Parallel build with as many threads as possible!")
if(MULTITHREADED_BUILD)
    if(${CMAKE_GENERATOR} MATCHES "Unix Makefiles")
            file(COPY ${ApproxMVBB_ROOT_DIR}/cmake/parallelmake.sh DESTINATION ${PROJECT_BINARY_DIR}
                FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
                NO_SOURCE_PERMISSIONS
            )
            SET(CMAKE_MAKE_PROGRAM "${PROJECT_BINARY_DIR}/parallelmake.sh")
            MESSAGE(STATUS "Set make program to ${PROJECT_BINARY_DIR}/parallelmake.sh")
    elseif(MSVC)
      SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" "/MP")
      MESSAGE(STATUS "Added parallel build arguments to CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
    endif()
endif()
# ========================================================================================================================================
cmake --build . -j 24