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


Answers:


94

对于现代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}>")

12
请注意,target_compile_options 添加了选项,因此您可以像这样修改最后一行以使其更具可读性)

2
@ComicSansMS很好的答案,也是我在互联网上可以找到的最好的(也是最新的)。谢谢!
Ela782 2015年

如果我想在全球范围内拥有相同的严格编译标志集,那么最好的现代方法是什么?使用target_compile_options为不同的目标一次又一次地指定相同的标志似乎是个坏主意
user3667089

1
@ user3667089特定于目标的属性通常由变量或目录属性初始化。相应属性的手册页会告诉您确切的内容。如果是编译选项,则COMPILE_OPTIONSdirectory属性将执行此操作。您可以使用add_compile_options命令进行设置。通常,这是一种很好的方法,但是选择很少。
ComicSansMS

6
@ComicSansMS什么用PUBLICtarget_compile_options
Ramana Reddy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.