将目标属性添加到 CMake 中现有的导入库

Posted

技术标签:

【中文标题】将目标属性添加到 CMake 中现有的导入库【英文标题】:Add target properties to an existing imported library in CMake 【发布时间】:2019-03-09 20:39:57 【问题描述】:

外部项目由 CMake 构建并安装在通过 CMAKE_PREFIX_PATH 可见的目录中。由于它是 CMake 项目,它会安装正确的 .cmake 文件。在这些自动生成的文件中,会创建一个 EXPORTED 目标并设置所有必需的属性。

我想做的是 - 在不修改原始 CMakeLists.txt 的情况下 - 添加我需要的编译定义,以便正确包含此库中的标头。

到目前为止,我已经尝试了两种方法:

重新添加库并正常指定定义

add_library(_external_lib_name_ INTERFACE IMPORTED)
target_compile_definitions(_external_lib_name_ INTERFACE FOO_BAR)

这不起作用,因为目标的所有已设置属性(如包含目录)都将被忽略。

只需添加定义

target_compile_definitions(_external_lib_name_ INTERFACE FOO_BAR)

这次CMake抱怨:

CMake Error at foo.cmake:1 (target_compile_definitions):
  Cannot specify compile definitions for target "_external_lib_name_" which is not built by this project.

目前我正在考虑代理目标:

add_library(_proxy_target_ INTERFACE)
target_link_libraries(_proxy_target_ INTERFACE _external_lib_name_)
target_compile_definitions(_proxy_target_ INTERFACE FOO_BAR)

虽然这可能有效,但有谁知道是否有更好的方法来修改导入的目标?

更新

使用 Tsyvarev 的回答,我能够使其工作,但还有另一个问题:为了正确修改目标,我需要 include 一个文件,首先是 find_package,然后是 set_property。如果我不使用include,而是使用标准CMakeLists.txtadd_subdirectory,则目标会保留旧属性。

【问题讨论】:

【参考方案1】:

带有 INTERFACE 关键字的命令 target_compile_definitions 附加到属性 INTERFACE_COMPILE_DEFINITIONS,但不适用于 IMPORTED 目标。您需要使用直接与目标属性一起使用的命令:

set_property(TARGET _external_lib_name_ APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS FOO_BAR)

【讨论】:

像魅力一样工作!遗憾的是,文档中没有关于它的任何内容(为什么手动属性设置有效,但 target_* 命令无效)。 嗯,有趣的是:older target_compile_definitions documentation 指出该命令不适用于 IMPORTED 目标,但 newer one 却指出了 ALIAS 目标。可能,随着 CMake 的发展,事情已经发生了变化。

以上是关于将目标属性添加到 CMake 中现有的导入库的主要内容,如果未能解决你的问题,请参考以下文章

CMake:隐藏子目标的-WShadow全局编译标志

如何为插件组件设置 CMAKE 导入目标?

如何在 CMake 中为外部 INTERFACE_SOURCES 设置编译标志?

Java中现有的树库? [复制]

如何为依赖目标添加 cmake 定义?

使用CMake自动将文件夹中的所有文件添加到目标?