CMake INTERFACE接口库添加自定义许可属性报错解决方案咨询
问题原因
CMake 对 INTERFACE 类型的目标有严格的属性白名单限制,默认仅允许使用官方预设的内置属性,避免非传递性的自定义属性被错误注入依赖传递链路。你当前的实现仅定义了普通的目标属性,没有声明该属性可用于 INTERFACE 类型目标,因此触发权限类报错。
另外你当前把 define_property 放在函数内部,每次调用函数都会重复执行三次属性定义,属于冗余操作,实际只需要全局定义一次即可。
正确实现方案
方案1:高版本CMake原生支持(CMake 3.19+)
在定义自定义属性时添加 CUSTOM 和 INTERFACE_EXPORT 参数,明确告知CMake该属性允许挂载到INTERFACE目标上,修改后的代码如下:
# 移到函数外部全局定义一次即可 define_property( TARGET PROPERTY MY_LIC_ORIGINAL CUSTOM INTERFACE_EXPORT BRIEF_DOCS "Original file name on system" FULL_DOCS "...") define_property( TARGET PROPERTY MY_LIC_CHECKEDIN CUSTOM INTERFACE_EXPORT BRIEF_DOCS "File name checked-in git (with md5sum appended on disk)" FULL_DOCS "...") define_property( TARGET PROPERTY MY_LIC_FLAGS CUSTOM INTERFACE_EXPORT BRIEF_DOCS "Flags for license checks or manual generation" FULL_DOCS "...") function(myNewExternal NAME) _myParseExternalParameters(EXTARGS ${ARGN}) if(NOT DEFINED EXTARGS_TARGET) message(FATAL_ERROR "myNewExternal missing TARGET") endif() add_library(${NAME} INTERFACE) target_link_libraries(${NAME} INTERFACE ${EXTARGS_TARGET}) # 后续可以正常通过set_property/get_property使用三个自定义属性 endfunction()
方案2:全版本CMake兼容方案
如果需要兼容3.19以下的CMake版本,可以放弃挂载目标属性,改用全局属性关联目标名作为唯一key存储许可证信息:
function(myNewExternal NAME) _myParseExternalParameters(EXTARGS ${ARGN}) if(NOT DEFINED EXTARGS_TARGET) message(FATAL_ERROR "myNewExternal missing TARGET") endif() add_library(${NAME} INTERFACE) target_link_libraries(${NAME} INTERFACE ${EXTARGS_TARGET}) # 存储许可证属性示例 set_property(GLOBAL PROPERTY MY_LIC_ORIGINAL_${NAME} "${EXTARGS_LIC_PATH}") set_property(GLOBAL PROPERTY MY_LIC_CHECKEDIN_${NAME} "${CHECKEDIN_PATH}") set_property(GLOBAL PROPERTY MY_LIC_FLAGS_${NAME} "${LIC_FLAGS}") endfunction() # 取值示例 function(get_lic_info TARGET OUT_VAR) get_property(val GLOBAL PROPERTY MY_LIC_ORIGINAL_${TARGET}) set(${OUT_VAR} ${val} PARENT_SCOPE) endfunction()
这种方案没有CMake版本要求,实现逻辑简单,只是读写属性时需要拼接目标名作为全局属性的key。
内容的提问来源于stack exchange,提问作者Johannes Schaub - litb
相关产品推荐
相关产品推荐

