问题描述
我们希望为每个使用过的库添加一个许可证文件,以及一种比较许可证以检测它们是否发生变化的机制。因此,我们将其许可文件添加到每个库(Boost、Qt 等)中,并有一个签入副本。
我们认为我们可以为此添加一个我们自己的接口库,使用我们自己的名称,并将实际的 CMake 导入库链接到它,例如 Qt6::Core
或 Boost::filesystem
。但是将许可证文件名添加为属性会导致错误。最后只链接到我们自己的接口库。
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})
# add property for the original files
define_property(
TARGET
PROPERTY MY_LIC_ORIGINAL
BRIEF_DOCS "Original file name on system"
FULL_DOCS "...")
# add property for the checked-in files
define_property(
TARGET
PROPERTY MY_LIC_CHECKEDIN
BRIEF_DOCS "File name checked-in git (with md5sum appended on disk)"
FULL_DOCS "...")
# add property for the flags (checked(c),printed(p))
define_property(
TARGET
PROPERTY MY_LIC_FLAGS
BRIEF_DOCS "Flags for license checks or manual generation"
FULL_DOCS "...")
endfunction()
CMake Error at cmake/700-externals.cmake:39 (set_property):
INTERFACE_LIBRARY targets may only have whitelisted properties. The
property "MY_LIC_ORIGINAL" is not allowed.
解决方法
INTERFACE
库的自定义属性必须以 INTERFACE_
为前缀。这是一个用于验证的简单 CMakeLists.txt:
cmake_minimum_required(VERSION 3.21)
project(test NONE)
add_library(foo INTERFACE)
set_property(TARGET foo PROPERTY INTERFACE_CUSTOM "bar")
get_property(value TARGET foo PROPERTY INTERFACE_CUSTOM)
message(STATUS "foo.INTERFACE_CUSTOM = \"${value}\"")
在命令行:
$ cmake -S . -B build
-- foo.INTERFACE_CUSTOM = "bar"
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
请注意,除非为其定义了几个简单的兼容性规则之一,否则自定义 INTERFACE
属性不会传播。有关详情,请参阅 compatible interface properties。