add_compile_options 和 SET(CMAKE_CXX_FLAGS...) 的区别

Difference between add_compile_options and SET(CMAKE_CXX_FLAGS...)

这个问题与Instruct Cmake to use CXX and CXXFLAGS when driving link?有关在前一个问题中,我们试图指示CMake在调用链接器时使用CXXFLAGS

add_compile_options

我们发现如下代码

if (CMAKE_VERSION VERSION_LESS 2.8.12)
    add_definitions(-foo)
else()
    add_compile_options(-foo)
endif()

message(STATUS, "CXXFLAGS: ${CMAKE_CXX_FLAGS}")

产生输出

CXXFLAGS:

SET CMAKE_CXX_FLAGS

我们发现如下代码

SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -foo" )

message(STATUS, "CXXFLAGS: ${CMAKE_CXX_FLAGS}")

产生输出

CXXFLAGS: -foo

问题

我们发现 CMake 在这两种情况下都会使用 -foo 创建目标文件。所以 -foo 肯定会进入 CXXFLAGS

第一套CMake代码和第二套CMake代码有什么区别?

为什么 CMAKE_CXX_FLAGS 在一个实例中未设置,而在另一个实例中设置?

  • CMAKE_CXX_FLAGS 用于为所有 C++ 目标添加标志。这对于传递一般参数(如警告级别)或选择所需的 C++ 标准很方便。它对 C 或 Fortran 目标没有影响,用户可能会传递其他标志。

  • add_compile_options 将选项添加到目录及其子目录中的所有目标。如果您在目录中有一个库并且您想要向与该库相关但与所有其他目标无关的所有目标添加选项,这将很方便。此外,add_compile_options 可以处理带有 generator expressions. The documentation 明确声明的参数,即

This command can be used to add any options, but alternative commands exist to add preprocessor definitions (target_compile_definitions() and add_definitions()) or include directories (target_include_directories() and include_directories()).

  • add_definitions 旨在传递 -DFOO -DBAR=32 类型的预处理器值(Windows 上的 /D),它定义和设置预处理器变量。您可以传递任何标志,但上述形式的标志会被检测并添加到 [COMPILE_DEFINITIONS][2] 属性,您可以稍后读取和更改。在这里,您也可以使用 生成器表达式 documentation 提到了目录、目标和源文件的范围。

对于给定的目标,CMake 将从 CMAKE_CXX_FLAGS、目标和目录的 COMPILE_DEFINITIONS 以及所有影响目标的 add_compile_options 收集所有标志。
CMAKE_CXX_FLAGS 不会被其他命令改变,反之亦然。这将违反这些命令的范围。