如何在 CMake 中配置可移植并行构建?
-
12-12-2019 - |
题
无论使用哪种构建工具,是否都可以进行并行构建?
在Unix下我们可以添加 make -jN
其中 N 是线程数,在 Windows 下我添加到 CXX_FLAG "/MP"
然后在 Visual Studio 中使用它来并行构建...(?)我怎样才能使我的版本这样 CMAKE_MAKE_PROGRAM
当我运行 CMake 时并不总是扩展?
什么是通用解决方案?
我想出了这个:
# 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()
解决方案
使用 CMake 3.12 这是可能的。从发行说明来看:
获得的“ cmake(1)”构建工具模式(“ cmake –build”)获得了“ - 并行[]和“ -j []”选项,以指定并行构建级别。它们映射到本机构建工具的相应选项。
正如 dkg 所提到的, ,还可以设置环境变量 CMAKE_BUILD_PARALLEL_LEVEL
.
CMake 文档链接:
其他提示
如果您有 CMake v2.8.8 或更高版本,您可以使用 忍者 作为替代 GNU make
:
mkdir build
cd build
cmake -G Ninja ..
ninja # Parallel build (no need -j12)
或者
mkdir build
cd build
cmake -G Ninja ..
cmake --build . # Parallel build using Ninja
如您所见,无需使用 CMAKE_MAKE_PROGRAM
, ,默认情况下构建是并行运行的,根据可用的 CPU 核心优化作业数量。
Ninja 基于低级 JSON 配置来加速启动阶段。因此它的 JSON 配置不容易手工编写,我总是使用高级工具/IDE 生成它:
- CMake v2.8.8 (2012)
- Qt 创建者 v2.6 (2012)
- KDevelop v4.6 (2013)
- 介子 在 Linux 上 (2013)
- ...请参阅 Ninja 配置的生成器 https://github.com/ninja-build/ninja/wiki/List-of-generators-having-ninja-build-files
由于 C++ 构建通常需要大量内存,因此您的计算机必须提供与 CPU 核心数量一样多的内存。
正如所指出的 鲁斯兰, 、CMake 3.12 (2018)有一个 新的选择 cmake --build -j <N>
将构建限制为 <N>
核心(作业)从而限制内存消耗(另请参阅 文档)。如果您使用较旧的 CMake 版本,您仍然可以使用 cmake --build -- -j <N>
. 。选项 --
告诉 CMake 将其余部分直接传递给底层构建工具,这里是 Ninja。
您无法跨平台执行此操作。-jN 选项是 make 的一个参数,而不是生成的 Makefile 的一部分。但是,您可以让 CMake 生成一个 Bash 脚本,该脚本使用 -jN 为您的项目运行 make(其中脚本查找您拥有的核心数量)。
我已经决定写一篇 parallelmake.sh
脚本为 Unix Makefiles
基于发电机。这是在这里完成的: https://github.com/gabyx/ApproxMVBB
以及CMake文件中的相关部分:
https://github.com/gabyx/ApproxMVBB/blob/master/CMakeLists.txt#L89
# 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()
# ========================================================================================================================================