1.7 切换构建类型

NOTE:此示例代码可以在 https://github.com/dev-cafe/cmake-cookbook/tree/v1.0/chapter-01/recipe-07 中找到,包含一个C++/C示例。该示例在CMake 3.5版(或更高版本)中是有效的,并且已经在GNU/Linux、macOS和Windows上进行过测试。

CMake可以配置构建类型,例如:Debug、Release等。配置时,可以为Debug或Release构建设置相关的选项或属性,例如:编译器和链接器标志。控制生成构建系统使用的配置变量是CMAKE_BUILD_TYPE。该变量默认为空,CMake识别的值为:

  1. Debug:用于在没有优化的情况下,使用带有调试符号构建库或可执行文件。
  2. Release:用于构建的优化的库或可执行文件,不包含调试符号。
  3. RelWithDebInfo:用于构建较少的优化库或可执行文件,包含调试符号。
  4. MinSizeRel:用于不增加目标代码大小的优化方式,来构建库或可执行文件。

具体实施

示例中,我们将展示如何为项目设置构建类型:

  1. 首先,定义最低CMake版本、项目名称和支持的语言:

    1. cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
    2. project(recipe-07 LANGUAGES C CXX)
  2. 然后,设置一个默认的构建类型(本例中是Release),并打印一条消息。要注意的是,该变量被设置为缓存变量,可以通过缓存进行编辑:

    1. if(NOT CMAKE_BUILD_TYPE)
    2. set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
    3. endif()
    4. message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
  3. 最后,打印出CMake设置的相应编译标志:

    1. message(STATUS "C flags, Debug configuration: ${CMAKE_C_FLAGS_DEBUG}")
    2. message(STATUS "C flags, Release configuration: ${CMAKE_C_FLAGS_RELEASE}")
    3. message(STATUS "C flags, Release configuration with Debug info: ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
    4. message(STATUS "C flags, minimal Release configuration: ${CMAKE_C_FLAGS_MINSIZEREL}")
    5. message(STATUS "C++ flags, Debug configuration: ${CMAKE_CXX_FLAGS_DEBUG}")
    6. message(STATUS "C++ flags, Release configuration: ${CMAKE_CXX_FLAGS_RELEASE}")
    7. message(STATUS "C++ flags, Release configuration with Debug info: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
    8. message(STATUS "C++ flags, minimal Release configuration: ${CMAKE_CXX_FLAGS_MINSIZEREL}")
  4. 验证配置的输出:

    1. $ mkdir -p build
    2. $ cd build
    3. $ cmake ..
    4. ...
    5. -- Build type: Release
    6. -- C flags, Debug configuration: -g
    7. -- C flags, Release configuration: -O3 -DNDEBUG
    8. -- C flags, Release configuration with Debug info: -O2 -g -DNDEBUG
    9. -- C flags, minimal Release configuration: -Os -DNDEBUG
    10. -- C++ flags, Debug configuration: -g
    11. -- C++ flags, Release configuration: -O3 -DNDEBUG
    12. -- C++ flags, Release configuration with Debug info: -O2 -g -DNDEBUG
    13. -- C++ flags, minimal Release configuration: -Os -DNDEBUG
  5. 切换构建类型:

    1. $ cmake -D CMAKE_BUILD_TYPE=Debug ..
    2. -- Build type: Debug
    3. -- C flags, Debug configuration: -g
    4. -- C flags, Release configuration: -O3 -DNDEBUG
    5. -- C flags, Release configuration with Debug info: -O2 -g -DNDEBUG
    6. -- C flags, minimal Release configuration: -Os -DNDEBUG
    7. -- C++ flags, Debug configuration: -g
    8. -- C++ flags, Release configuration: -O3 -DNDEBUG
    9. -- C++ flags, Release configuration with Debug info: -O2 -g -DNDEBUG
    10. -- C++ flags, minimal Release configuration: -Os -DNDEBUG

工作原理

我们演示了如何设置默认构建类型,以及如何(从命令行)覆盖它。这样,就可以控制项目,是使用优化,还是关闭优化启用调试。我们还看到了不同配置使用了哪些标志,这主要取决于选择的编译器。需要在运行CMake时显式地打印标志,也可以仔细阅读运行CMake --system-information的输出,以了解当前平台、默认编译器和语言的默认组合是什么。下一个示例中,我们将讨论如何为不同的编译器和不同的构建类型,扩展或调整编译器标志。

更多信息

我们展示了变量CMAKE_BUILD_TYPE,如何切换生成构建系统的配置(这个链接中有说明: https://cmake.org/cmake/help/v3.5/variable/CMAKE_BUILD_TYPE.html )。Release和Debug配置中构建项目通常很有用,例如:评估编译器优化级别的效果。对于单配置生成器,如Unix Makefile、MSYS Makefile或Ninja,因为要对项目重新配置,这里需要运行CMake两次。不过,CMake也支持复合配置生成器。这些通常是集成开发环境提供的项目文件,最显著的是Visual Studio和Xcode,它们可以同时处理多个配置。可以使用CMAKE_CONFIGURATION_TYPES变量可以对这些生成器的可用配置类型进行调整,该变量将接受一个值列表(可从这个链接获得文档:https://cmake.org/cmake/help/v3.5/variable/CMAKE_CONFIGURATION_TYPES.html)。

下面是对Visual Studio的CMake调用:

  1. $ mkdir -p build
  2. $ cd build
  3. $ cmake .. -G"Visual Studio 12 2017 Win64" -D CMAKE_CONFIGURATION_TYPES="Release;Debug"

将为Release和Debug配置生成一个构建树。然后,您可以使--config标志来决定构建这两个中的哪一个:

  1. $ cmake --build . --config Release

NOTE:当使用单配置生成器开发代码时,为Release版和Debug创建单独的构建目录,两者使用相同的源代码。这样,就可以在两者之间切换,而不用重新配置和编译。