C++ CMake 中的 set_target_properties 是否覆盖 CMAKE_CXX_FLAGS?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5096881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:23:04  来源:igfitidea点击:

Does set_target_properties in CMake override CMAKE_CXX_FLAGS?

c++cmakecompiler-flags

提问by Milan Hanus

At the beginning of my CMake project, I'm setting general compilation flags in the variable CMAKE_CXX_FLAGS, like

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

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

Later on, I need to append additional configuration-specific compilation flags (stored in BUILD_FLAGS). Can I use the following command for this:

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

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

or do I have to add the CMAKE_CXX_FLAGS manually:

还是我必须手动添加 CMAKE_CXX_FLAGS :

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

to prevent CMAKE_CXX_FLAGS being overriden by BUILD_FLAGS?

防止 CMAKE_CXX_FLAGS 被 BUILD_FLAGS 覆盖?

采纳答案by richq

Use the first one:

使用第一个:

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

The flags stored in BUILD_FLAGS are appended after CMAKE_CXX_FLAGS when compiling the sources of TARGET. The documentation hints at this, but I've just tried it to make sure.

编译 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.

编译标志

   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.

The full command line will be the equivalent of:

完整的命令行相当于:

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

And as Ramon said, you can always check with make VERBOSE=1.

正如 Ramon 所说,您可以随时使用make VERBOSE=1.

回答by olibre

The accepted answeris still working but outdated since 2013.
This answer is based and new functions from CMake v2.8.12, v3.3 and v3.13.

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

Since CMake-2.8.12 (2013)

自 CMake-2.8.12 (2013)

Two new commands to set CMAKE_CXX_FLAGS:

要设置的两个新命令CMAKE_CXX_FLAGS

The documentation of last version has not changed a lot since cmake-2.8.12:

cmake-2.8.12以来,上一版本的文档没有太大变化:

In you case you can use:

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

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

Or simply if you have a single target:

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

add_compile_options(${BUILD_FLAGS})

More examples

更多例子

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

Deprecated COMPILE_FLAGS

已弃用 COMPILE_FLAGS

cmake-3.0documentationflags COMPILE_FLAGSas deprecated:

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

COMPILE_FLAGS

Additional flags to use when compiling this target's sources.

The COMPILE_FLAGSproperty sets additional compiler flags used to build sources within the target. Use COMPILE_DEFINITIONSto pass additional preprocessor definitions.

This property is deprecated. Use the COMPILE_OPTIONSproperty or the target_compile_optionscommand instead.

COMPILE_FLAGS

编译此目标的源时要使用的其他标志。

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

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

If you still want to use set_target_properties()you may use COMPILE_OPTIONSinstead of COMPILE_FLAGS:

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

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

Since CMake-3.3 (2015)

自 CMake-3.3 (2015)

Anton Petrovsuggests to use generator expressionsas presented in an answer of ar31.

Anton Petrov建议使用生成器表达式,ar31回答中所示

The CMake generator expressionsapplies your ${BUILD_FLAGS}to:

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

  • C++ language using $<COMPILE_LANGUAGE:CXX>(can also be C, CUDA...)
  • Clang compiler using $<CXX_COMPILER_ID:Clang>
    (can also be GNUfor gcc, or MSVCfor Visual C++... see full list)
    (use $<C_COMPILER_ID:Clang>instead if language is C)
  • and more as supported C++ featureor compiler version... (see documentation)
  • C++ 语言使用$<COMPILE_LANGUAGE:CXX>(也可以是CCUDA...)
  • Clang 编译器使用$<CXX_COMPILER_ID:Clang>
    (也可以GNU用于gcc,或MSVC用于 Visual C++...请参阅完整列表
    $<C_COMPILER_ID:Clang>如果语言是 C,请改用)
  • 以及更多支持的 C++ 功能编译器版本......(请参阅文档

In you case you can use:

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

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

or about compilers:

或关于编译器:

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}>)

Since CMake-3.13 (2018)

自 CMake-3.13 (2018)

A new function target_link_options()allow to pass options to the linker, as mentioned by Craig Scott.

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

Different options for C and C++ files

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

The best way is to distinguish C files and C++ files using two different targets.

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