CMake中的set_target_properties是否会覆盖CMAKE_CXX_FLAGS?

时间:2011-02-23 20:46:31

标签: c++ cmake compiler-flags

在我的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}")

防止BUILD_FLAGS覆盖CMAKE_CXX_FLAGS?

2 个答案:

答案 0 :(得分:51)

使用第一个:

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

在编译TARGET的源时,在CMAKE_CXX_FLAGS之后附加存储在BUILD_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

答案 1 :(得分:49)

自2013年以来,已接受的answer仍然有效但过时了 这个答案是基于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 documentation标记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建议使用generator expressions中提供的answer of ar31

CMake 生成器表达式将您的${BUILD_FLAGS}应用于:

  • 使用$<COMPILE_LANGUAGE:CXX>的C ++语言(也可以是CCUDA ...)
  • 使用$<CXX_COMPILER_ID:Clang>的Clang编译器 (对于GNU也可以是gcc,对于Visual C ++也可以是MSVC ...请参阅full list
    (如果语言为C,则使用$<C_COMPILER_ID:Clang>
  • 以及支持的C ++功能编译器版本 ...(参见documentation

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

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)

以来

新函数target_link_options()允许将选项传递给链接器,如Craig Scott所述。

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

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