C++ 现代CMake中预处理器的定义
我目前正在学习CMake,不想养成坏习惯,因为在CMake中总有两种方法可以做某事(从我所看到的来看,旧方法和现代方法) 在阅读了一些关于CMake中预处理器的文档并查看本文之后: 我得出的结论是,我可以将预处理器定义为:C++ 现代CMake中预处理器的定义,c++,cmake,preprocessor,C++,Cmake,Preprocessor,我目前正在学习CMake,不想养成坏习惯,因为在CMake中总有两种方法可以做某事(从我所看到的来看,旧方法和现代方法) 在阅读了一些关于CMake中预处理器的文档并查看本文之后: 我得出的结论是,我可以将预处理器定义为: add\u compile\u定义(FOO) target\u compile\u定义(myTarget PRIVATE FOO) 添加定义(-DFOO) 在一些测试之后,它们确实按照预期工作,并定义FOO 但现在我的问题是,我应该使用哪种最“现代”的方式,以及每个函数
add\u compile\u定义(FOO)
target\u compile\u定义(myTarget PRIVATE FOO)
添加定义(-DFOO)
FOO
但现在我的问题是,我应该使用哪种最“现代”的方式,以及每个函数之间的真正区别,我注意到的唯一区别是,如果我使用
target\u compile\u定义(myTarget PUBLIC FOO)
然后在父目标中定义FOO
。现代CMake的总趋势是从全局设置转向以目标为中心的设置。仅基于这一规则,target\u compile\u definitions()
是最现代的方法。它还允许控制设置是仅在目标(PRIVATE
)中使用,还是在使用此目标的其他目标(INTERFACE
)中使用,还是同时在两者中使用(PUBLIC
)。在内部,它通过修改目标的属性COMPILE\u DEFINITIONS
和INTERFACE\u COMPILE\u DEFINITIONS
来工作
下一个关于现代性的问题是add\u compile\u definitions()
。将宏定义添加到当前目录和子目录中定义的所有目标中;在这方面,其范围类似于include_directories()
。在内部,它通过修改当前目录的COMPILE\u DEFINITIONS
属性来工作。所以:它仍然使用正确的“现代”机制,但是是面向目录的,而不是面向目标的
在列表的底部,我们有一个非常古老的函数
add\u definitions()
。在现代CMake中,这是最好避免的。虽然用于指定预处理器定义(因此得名),但它实际上允许在中传递任意编译器选项(这也是您需要指定-DFOO
而不是仅将FOO
作为其参数的原因)。它试图确定传入的内容是否实际上是预处理器宏定义,在这种情况下,它们将被移动到目录的COMPILE\u definitions
属性中。如果它们没有被识别出来(对于具有复杂替换字符串的宏可能会发生这种情况),它们将被留在标志列表中。事实上,target\u compile\u definitions
是添加预处理宏的最合适的方法
您应该使用它的原因之一是
target\u compile\u定义(myTarget PUBLIC FOO)
将FOO
传播到依赖项,因为您可以按目标而不是按文件夹正确定义它们。现在,您可以将这些定义附加到目标,以便依赖项也可以声明它们。如果您尝试从不同的文件夹创建目标,您将更准确地看到这种行为,并看到它实际上比以前非常不可靠的行为更有意义
例如,在Windows上,所有常用的“导出”宏都应该以这种方式声明,并且
私有
,这样它们就不会被传播,因为它们实际上是私有定义。如何使用目标编译定义添加与定义3.21版
等价的内容(myTarget PUBLIC VER=3.21)
应该可以做到这一点。