64

在我的 CMake 项目开始时,我在变量 CMAKE_CXX_FLAGS 中设置通用编译标志,例如

set(CMAKE_CXX_FLAGS "-W -Wall ${CMAKE_CXX_FLAGS}")

稍后,我需要附加额外的特定于配置的编译标志(存储在 BUILD_FLAGS 中)。我可以为此使用以下命令吗?

set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS ${BUILD_FLAGS})

还是我必须手动添加 CMAKE_CXX_FLAGS:

set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BUILD_FLAGS}")

防止 CMAKE_CXX_FLAGS 被 BUILD_FLAGS 覆盖?

4

2 回答 2

61

自 2013 年以来,已接受的答案仍然有效,但已过时。
此答案基于 CMake v2.8.12、v3.3 和 v3.13 的新功能。

自 CMake-2.8.12 (2013)

要设置的两个新命令CMAKE_CXX_FLAGS

自cmake-2.8.12以来,最新版本的文档没有太大变化:

在您的情况下,您可以使用:

target_compile_options(${TARGET} PRIVATE ${BUILD_FLAGS})

或者只是如果你有一个目标:

add_compile_options(${BUILD_FLAGS})

更多示例

target_compile_options(mylib PRIVATE   -O2) # only internal
target_compile_options(mylib INTERFACE -gl) # only external
target_compile_options(mylib PUBLIC    -g)  # same as PRIVATE + INTERFACE

# multiple targets and flags
target_compile_options(mylib1 mylib2 PRIVATE -Wall -Wextra)

target_compile_options(    mylib PUBLIC -DUSEXX)  # Bad
target_compile_definitions(mylib PUBLIC -DUSEXX)  # OK

add_compile_options(-Wall -Wextra) # for all targets in current directory
add_compile_options(-DUSEXX)       # Bad
add_definitions(-DUSEXX)           # OK

已弃用COMPILE_FLAGS

cmake-3.0文档标记COMPILE_FLAGS为已弃用:

COMPILE_FLAGS

编译此目标的源时要使用的附加标志。

COMPILE_FLAGS属性设置用于在目标中构建源的附加编译器标志。用于COMPILE_DEFINITIONS传递额外的预处理器定义。

此属性已弃用。请改用COMPILE_OPTIONS属性或 target_compile_options命令。

如果您仍想使用set_target_properties(),您可以使用COMPILE_OPTIONS代替COMPILE_FLAGS

set_target_properties(${TARGET} PROPERTIES COMPILE_OPTIONS ${BUILD_FLAGS})

自 CMake-3.3 (2015)

Anton Petrov建议使用ar31的答案中提出的生成器表达式

CMake生成器表达式适用${BUILD_FLAGS}于:

  • C++ 语言使用$<COMPILE_LANGUAGE:CXX>(也可以是CCUDA...)
  • 使用 Clang 编译器$<CXX_COMPILER_ID:Clang>
    (也可以是GNUforgccMSVCfor Visual C++... 查看完整列表
    $<C_COMPILER_ID:Clang>如果语言是 C,则使用)
  • 以及更多受支持的 C++ 功能编译器版本...(请参阅文档

在您的情况下,您可以使用:

target_compile_options(${TARGET} PRIVATE
          $<$<COMPILE_LANGUAGE:CXX>:${BUILD_FLAGS_FOR_CXX}>
          $<$<COMPILE_LANGUAGE:C>:${BUILD_FLAGS_FOR_C}>)

或关于编译器:

target_compile_options(${TARGET} PRIVATE
          $<$<CXX_COMPILER_ID:Clang>:${BUILD_FLAGS_FOR_CLANG}>
          $<$<CXX_COMPILER_ID:GNU>:${BUILD_FLAGS_FOR_GCC}>
          $<$<CXX_COMPILER_ID:MSVC>:${BUILD_FLAGS_FOR_VISUAL}>)

自 CMake-3.13 (2018)

正如Craig Scott所提到的,一个新函数target_link_options()允许将选项传递给链接器。

C 和 C++ 文件的不同选项

最好的方法是使用两个不同的目标来区分 C 文件和 C++ 文件。

于 2015-06-26T14:20:59.737 回答
59

使用第一个:

set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS ${BUILD_FLAGS})

在编译 TARGET 的源代码时,将存储在 BUILD_FLAGS 中的标志附加在 CMAKE_CXX_FLAGS 之后。文档提示了这一点,但我只是尝试过确认。

COMPILE_FLAGS

   Additional flags to use when compiling this target's sources. 
   
   The COMPILE_FLAGS property sets additional compiler flags used to
   build sources within the target.  Use COMPILE_DEFINITIONS to
   pass additional preprocessor definitions.

完整的命令行相当于:

${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS} -o foo.o -c foo.cc

正如拉蒙所说,您可以随时查看make VERBOSE=1.

于 2011-02-24T07:18:00.283 回答