CMake:CMake 构建类型 (DCMAKE_BUILD_TYPE) 有什么作用?

CMake: What do CMake build types (DCMAKE_BUILD_TYPE) do?

我正在使用 CMake(在 CLion IDE 中,但这对于本次讨论不重要)。到目前为止,我一直在使用 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") 之类的东西来为 GCC 设置编译器选项。我假设 CMake 将这些直接传递给编译器。然而,CMake 应该是独立于平台的,并且(至少在原则上)能够使用不同的编译器构建相同的代码。这是否意味着应该采取不同的做法?

我一直在考虑使用构建配置。例如,我假设使用构建类型标志调用 CMake:

cmake .. -DCMAKE_BUILD_TYPE="Release"

启用一些优化。然而,我无法找到关于这个标志究竟做什么的任何文档(可能是因为它取决于诸如所使用的编译器之类的事情)。我有两个问题:

  1. -DCMAKE_BUILD_TYPE="Release"(和其他版本类型)有什么作用(就像不知道构建发生的系统一样)?
  2. 查看构建时实际使用的编译器和 所有 选项的最佳方式是什么(在命令行中使用 CMake,在 CLion 之类的 IDE 中使用) ?

阅读 CMake 生成的 makefile 来查找标志对我来说似乎不是一个选择。我尝试为 Make 设置 VERBOSE=yes 但不知何故它没有给我编译器标志,只是一些“进入结束退出目录”。

  1. What does -DCMAKE_BUILD_TYPE="Release" (and other release types) do (as exactly as one can tell not knowing the system where the build happens)?

它启用核心 CMake 模块中定义的特定编译器选项,这些选项特定于目标系统。该文档并未准确解释每种构建类型的含义,但这些名称很常用。我理解 Release 的意思是“禁用调试,启用最高优化”。

例如,模块 Modules/Compiler/GNU.cmake 包含以下内容:

string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3 -DNDEBUG")

  1. What is the best way to view the compiler and all options actually being used at build time (both using CMake in command line and within an IDE like CLion) ?

一个方便的方法是编译数据库。格式指定 here 并使用选项 CMAKE_EXPORT_COMPILE_COMMANDS 启用。文件 compile_commands.json 将包含用于编译每个文件的确切命令。

如果使用别名 /usr/bin/c++,确定编译器可能需要额外的步骤,这很常见。


P.S。在许多情况下,在发布模式下启用调试可能很有用。虽然 RELWITHDEBINFO 这样做,但它不会启用最高优化(-O2 使用 GCC)。因此,我个人认为缺少默认选项。

它可以让您在“调试”和“发布”配置之间切换。这是什么意思?每种语言和配置都有默认的编译标志

CMAKE_<LANG>_FLAGS_<CONFIG>

从调试更改为发布,您正在更改 CMake 将用来设置 CMAKE_CXX_FLAGS 的标志。

直接设置 cmake 标志 "set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")" 在现代 cmake(版本 >= 3)中不是最佳实践。

为什么?

现代 CMake 是关于目标和属性的。如果您在项目中设置标志,则该标志会影响其他项目。 (并且在庞大的代码库中它会发生)所以注意变量和标志的可见性非常重要。考虑使用 target_compile_features, target_compile_options and target_compile_definitions。它使您的代码更具可读性且不易出错