CMake中COMPILE_DEFINITIONS参数异常及目标属性设置疑问
我来帮你理清这个CMake配置的问题——你遇到的参数错误,核心是没掌握COMPILE_DEFINITIONS属性的正确设置方式,以及混淆了自定义变量和目标属性的关联逻辑。
推荐方案:使用target_compile_definitions(CMake 3.0+ 首选)
CMake 3.0之后推荐用target_compile_definitions直接给目标添加编译定义,语法更直观,也避免手动处理属性的麻烦。针对你的静态库,只需要这样写:
add_library(modelutilities STATIC ${modelutilities_SRCS}) # 添加Qt5Widgets的编译定义,PRIVATE表示这些定义仅用于编译当前库,不暴露给依赖它的目标 target_compile_definitions(modelutilities PRIVATE ${Qt5Widgets_COMPILE_DEFINITIONS})
这里的PRIVATE是作用域关键字:
PRIVATE:编译定义仅对当前目标的源文件生效PUBLIC:既对当前目标生效,也会传递给依赖当前目标的其他目标INTERFACE:仅传递给依赖当前目标的其他目标,当前目标不使用
根据Qt的编译定义特性,用PRIVATE就足够了,因为Qt5Widgets_COMPILE_DEFINITIONS里的内容(比如QT_WIDGETS_LIB)只需要在编译你的modelutilities库时生效。
备选方案:用set_target_properties正确设置属性
如果你一定要用set_target_properties来设置COMPILE_DEFINITIONS,需要严格遵循它的语法:目标名 + PROPERTIES关键字 + 属性名 + 属性值。
如果是直接覆盖原有定义:
add_library(modelutilities STATIC ${modelutilities_SRCS}) set_target_properties(modelutilities PROPERTIES COMPILE_DEFINITIONS "${Qt5Widgets_COMPILE_DEFINITIONS}" )
如果是要追加定义(保留原有定义,再添加Qt的),需要先获取现有属性再拼接:
add_library(modelutilities STATIC ${modelutilities_SRCS}) # 获取目标当前的COMPILE_DEFINITIONS属性 get_target_property(existing_defs modelutilities COMPILE_DEFINITIONS) # 处理属性为空的情况 if(NOT existing_defs) set(existing_defs "") endif() # 追加Qt的编译定义 set_target_properties(modelutilities PROPERTIES COMPILE_DEFINITIONS "${existing_defs};${Qt5Widgets_COMPILE_DEFINITIONS}" )
你原来的错误原因
你之前写的set(modelutilities_COMPILE_DEFINE ${modelutilities_COMPILE_DEFINE} ${Qt5Widgets_COMPILE_DEFINITIONS})是在操作一个自定义变量,CMake不会自动把这个变量和目标的COMPILE_DEFINITIONS属性关联起来。之后用set_target_properties时,因为没有遵循正确的语法(缺少PROPERTIES关键字、属性名和值的对应关系),才触发了参数数量不正确的错误。
内容的提问来源于stack exchange,提问作者IlBeldus

