在CMake中设置通用编译标志的现代方法是什么?

Pet*_*ark 76 cmake

CMake提供了多种机制来获取编译器的标志:

在现代使用中,是否有一种方法比另一种方法更受欢迎?如果是这样的话?此外,该方法如何与MSVC等多种配置系统一起使用?

Com*_*sMS 79

对于现代CMake(版本2.8.12及更高版本),您应该使用target_compile_options,它在内部使用目标属性.

CMAKE_<LANG>_FLAGS是一个全局变量,最容易使用.它也不支持生成器表达式,它可以派上用场.

add_compile_options 基于目录属性,在某些情况下很好,但通常不是指定选项的最自然方式.

target_compile_options基于每个目标工作(通过设置COMPILE_OPTIONSINTERFACE_COMPILE_OPTIONS目标属性),这通常会产生最干净的CMake代码,因为源文件的编译选项由文件所属的项目决定(而不是放置在哪个目录中)在硬盘上).这具有额外的优点,即如果请求,它自动负责将选项传递给依赖目标.

尽管它们更加冗长,但是每个目标命令允许对不同的构建选项进行合理细粒度的控制,并且(根据我的个人经验)从长远来看最不可能引起麻烦.

理论上,您也可以直接使用相应的属性set_target_properties,但target_compile_options通常更具可读性.

例如,要foo使用生成器表达式基于配置设置目标的编译选项,您可以编写:

target_compile_options(foo PUBLIC "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>")
target_compile_options(foo PUBLIC "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")
Run Code Online (Sandbox Code Playgroud)

  • 请注意`target_compile_options`**添加**选项,因此您可以修改最后一行,如[this](http://pastebin.com/jCDW5Aa9),使其更具可读性) (11认同)
  • @ComicSansMS `target_compile_options` 中的 `PUBLIC` 有什么用? (6认同)
  • 请注意,如果“MY_DEBUG_OPTIONS”包含空格,则需要“SHELL:”前缀,如下所示:“target_compile_options(${NAME} PUBLIC $&lt;$&lt;CONFIG:DEBUG&gt;:SHELL:${MY_DEBUG_OPTIONS}&gt;)” 。否则,您将收到编译错误,因为 Cmake 会将编译器选项括在双引号中。 (3认同)
  • @ComicSansMS很棒的答案和我在互联网上找到的最好的(也是最新的).谢谢! (2认同)