7.切换构建类型

7.切换构建类型

切换构建类型


CMake可以配置构建类型,例如:Debug、Release等。配置时,可以为Debug或Release构建设置相关的选项或属性,
例如:编译器和链接器标志。控制生成构建系统使用的配置变量是CMAKE_BUILD_TYPE。该变量默认为空,CMake识别的值为:
Debug: 用于在没有优化的情况下,使用带有调试符号构建库或可执行文件。
Release: 用于构建的优化的库或可执行文件,不包含调试符号。
RelWithDebInfo:用于构建较少的优化库或可执行文件,包含调试符号。
MinSizeRel: 用于不增加目标代码大小的优化方式,来构建库或可执行文件。

具体实施


  1. 首先,定义最低CMake版本、项目名称和支持的语言:
1
2
cmake_minimum_required(VERSION 3.5)
project(hello-world LANGUAGES CXX)
  1. 然后,设置一个默认的构建类型(本例中是 Release ),并打印一条消息。要注意的是,该变量被设置为缓存变量,可以通过缓存进行编辑:
1
2
3
4
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif()
message(STATUS "##### Build type is: ${CMAKE_BUILD_TYPE}")
  1. 打印出CMake设置的相应编译标志:
1
2
3
4
5
6
7
8
message(STATUS "##### C flags, Debug: 	${CMAKE_C_FLAGES_DEBUG}")
message(STATUS "##### C flags, Release: ${CMAKE_C_FLAGES_RELEASE}")
message(STATUS "##### C flags, Release: ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
message(STATUS "##### C flags, minimal: ${CMAKE_C_FLAGS_MINISIZEREL}")
message(STATUS "##### C++ flags, Debug: ${CMAKE_CXX_FLAGS_DEBUG}")
message(STATUS "##### C++ flags, Release: ${CMAKE_CXX_FLAGS_RELEASE}")
message(STATUS "##### C++ flags, Release: ${CMAKE_CXX_FELWITHDEBINFO}")
message(STATUS "##### C++ flags, Minimal: ${CMAKE_CXX_FLAGS_MINISIZEREL}")
  1. 验证配置输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ mkdir build
$ cd build
$ cmake ..

-- The CXX compiler identification is GNU 10.2.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- ##### Build type is: Release
-- ##### C flags, Debug configuration:
-- ##### C flags, Release configuration:
-- ##### C flags, Release configuration with Debug info:
-- ##### C flags, minimal Release configuration:
-- ##### C++ flags, Debug configuration: -g
-- ##### C++ flags, Release configuration: -O3 -DNDEBUG
-- ##### C++ flags, Release configuration with Debug info: -O2 -g -DNDEBUG
-- ##### C++ flags, minimal Release configuration: -Os -DNDEBUG
-- Configuring done
-- Generating done
-- Build files have been written to: /d/Databases/Desktop/cmake/build

# 构建
$ cmake --build .

[ 33%] Building CXX object CMakeFiles/hello-world.dir/hello-world.cpp.o
[ 66%] Building CXX object CMakeFiles/hello-world.dir/Message.cpp.o
[100%] Linking CXX executable hello-world.exe
[100%] Built target hello-world

$ ls

CMakeCache.txt CMakeFiles Makefile cmake_install.cmake hello-world.exe
  1. 切换构建类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ cmake -D CMAKE_BUILD_TYPE=Debug ..

-- The CXX compiler identification is GNU 10.2.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- ##### Build type is: Debug
-- ##### C flags, Debug configuration:
-- ##### C flags, Release configuration:
-- ##### C flags, Release configuration with Debug info:
-- ##### C flags, minimal Release configuration:
-- ##### C++ flags, Debug configuration: -g
-- ##### C++ flags, Release configuration: -O3 -DNDEBUG
-- ##### C++ flags, Release configuration with Debug info: -O2 -g -DNDEBUG
-- ##### C++ flags, minimal Release configuration: -Os -DNDEBUG
-- Configuring done
-- Generating done
-- Build files have been written to: /d/Databases/Desktop/cmake/build

$ cmake --build .

[ 33%] Building CXX object CMakeFiles/hello-world.dir/hello-world.cpp.o
[ 66%] Building CXX object CMakeFiles/hello-world.dir/Message.cpp.o
[100%] Linking CXX executable hello-world.exe
[100%] Built target hello-world

$ ls

CMakeCache.txt CMakeFiles Makefile cmake_install.cmake hello-world.exe
  1. 多参数构建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 同时构建 Release 和 静态库
$ cmake -D CMAKE_BUILD_TYPE=Release -D USE_LIBRARY=ON ..

-- The CXX compiler identification is GNU 10.2.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- ##### Build type is: Release
-- ##### C flags, Debug configuration:
-- ##### C flags, Release configuration:
-- ##### C flags, Release configuration with Debug info:
-- ##### C flags, minimal Release configuration:
-- ##### C++ flags, Debug configuration: -g
-- ##### C++ flags, Release configuration: -O3 -DNDEBUG
-- ##### C++ flags, Release configuration with Debug info: -O2 -g -DNDEBUG
-- ##### C++ flags, minimal Release configuration: -Os -DNDEBUG
-- Configuring done
-- Generating done
-- Build files have been written to: /d/Databases/Desktop/cmake/build

$ cmake --build .

[ 25%] Building CXX object CMakeFiles/message.dir/Message.cpp.o
[ 50%] Linking CXX static library libmessage.a
[ 50%] Built target message
[ 75%] Building CXX object CMakeFiles/hello-world.dir/hello-world.cpp.o
[100%] Linking CXX executable hello-world.exe
[100%] Built target hello-world

# 编译出 libmessage.a
$ ls

CMakeCache.txt CMakeFiles Makefile cmake_install.cmake hello-world.exe libmessage.a

工作原理


我们演示了如何设置默认构建类型,以及如何(从命令行)覆盖它。这样,就可以控制项目,是使用优化,还是关闭优化启用调试。

我们还看到了不同配置使用了哪些标志,这主要取决于选择的编译器。

需要在运行CMake时显式地打印标志,也可以仔细阅读运行CMake --system-information的输出,以了解当前平台、默认编译器和语言的默认组合是什么。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cmake_minimum_required(VERSION 3.5)

project(hello-cmake LANGUAGES CXX)

if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
endif()

option(USE_LIBRARY OFF)

list(APPEND _sources Message.h Message.cpp)

message(STATUS "##### Build type is: ${CMAKE_BUILD_TYPE}")
message(STATUS "##### C flags, Debug configuration: ${CMAKE_C_FLAGS_DEBUG}")
message(STATUS "##### C flags, Release configuration: ${CMAKE_C_FLAGS_RELEASE}")
message(STATUS "##### C flags, Release configuration with Debug info: ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
message(STATUS "##### C flags, minimal Release configuration: ${CMAKE_C_FLAGS_MINSIZEREL}")
message(STATUS "##### C++ flags, Debug configuration: ${CMAKE_CXX_FLAGS_DEBUG}")
message(STATUS "##### C++ flags, Release configuration: ${CMAKE_CXX_FLAGS_RELEASE}")
message(STATUS "##### C++ flags, Release configuration with Debug info: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
message(STATUS "##### C++ flags, minimal Release configuration: ${CMAKE_CXX_FLAGS_MINSIZEREL}")

if (USE_LIBRARY)
add_library(message ${_sources})
add_executable(hello-world hello-world.cpp)
target_link_libraries(hello-world message)
else()
add_executable(hello-world hello-world.cpp ${_sources})
endif()