CMake 中 LINK_LIBRARIES 的递归列表

2024-05-20

我正在尝试获取链接到 CMake 中特定目标的所有库的绝对路径列表,以便在调用中使用add_custom_command。然而,get_target_property(_LINK_LIBRARIES ${TARGET} LINK_LIBRARIES只包括直接依赖项(即在target_link_libraries(${TARGET} ...) call).

因此,如果我链接另一个 CMake 目标,例如mylibrary,该列表将包括mylibrary,但仅作为名称且不具有传递链接库。由于此列表还可以包含任意复杂的生成器表达式,因此检查每个项目是否是目标并检索其LINK_LIBRARIES递归地是不可行的。此外,可以在稍后的时间点指定目标CMakeLists.txt and if(TARGET mylibrary)将被跳过。

For INCLUDE_DIRECTORIES and COMPILE_DEFINITIONS这很容易解决,因为尽管两者的行为相似get_target_property使用(除了链接目标显然不在列表中),形式的生成器表达式$<TARGET_PROPERTY:${TARGET},INCLUDE_DIRECTORIES>生成所需的递归所需包含和定义列表。然而,$<TARGET_PROPERTY:${TARGET},LINK_LIBRARIES>产生与以下相同的列表get_target_property变体。

如何检索所需的绝对路径列表?

示范:

cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)

file(WRITE a.cpp "void foo() {};\n")
file(WRITE b.cpp "int main(int, char**) { return 0; }\n")

find_package(Boost REQUIRED COMPONENTS filesystem system)

add_library(A STATIC a.cpp)
target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS})
target_link_libraries(A PUBLIC ${Boost_LIBRARIES})

# demonstrates (at configure time) that the LINK_LIBRARIES property can contain
# arbitrary generator expressions, making a recursive solution infeasible
get_target_property(A_LINK_LIBRARIES A LINK_LIBRARIES)
message(STATUS "A LINK_LIBARIES: ${A_LINK_LIBRARIES}")

add_executable(B b.cpp b_lists)
target_link_libraries(B PRIVATE A)
target_include_directories(B PRIVATE .)

get_target_property(B_INCLUDE_DIRECTORIES B INCLUDE_DIRECTORIES)
get_target_property(B_LINK_LIBRARIES B LINK_LIBRARIES)

# demonstrates (at compile time) that method 1 is not recursive while method 2 is (for INCLUDE_DIRECTORIES)
# demonstrates (at compile time) that the library list is never recursive
add_custom_command(
    OUTPUT b_lists
    COMMAND ${CMAKE_COMMAND} -E echo "B INCLUDE_DIRECTORIES 1: ${B_INCLUDE_DIRECTORIES}"
    COMMAND ${CMAKE_COMMAND} -E echo "B INCLUDE_DIRECTORIES 2: $<TARGET_PROPERTY:B,INCLUDE_DIRECTORIES>"
    COMMAND ${CMAKE_COMMAND} -E echo "B LINK_LIBRARIES 1: ${B_LINK_LIBRARIES}"
    COMMAND ${CMAKE_COMMAND} -E echo "B LINK_LIBRARIES 2: $<TARGET_PROPERTY:B,LINK_LIBRARIES>"
    DEPENDS A
)
set_source_files_properties(b_lists PROPERTIES SYMBOLIC TRUE)

Output:

(configure)
A LINK_LIBARIES: $<$<NOT:$<CONFIG:DEBUG>>:D:/libs/boost-1_55_0/lib/boost_filesystem-vc110-mt-1_55.lib>;$<$<CONFIG:DEBUG>:D:/libs/boost-1_55_0/lib/boost_filesystem-vc110-mt-gd-1_55.lib>;$<$<NOT:$<CONFIG:DEBUG>>:D:/libs/boost-1_55_0/lib/boost_system-vc110-mt-1_55.lib>;$<$<CONFIG:DEBUG>:D:/libs/boost-1_55_0/lib/boost_system-vc110-mt-gd-1_55.lib>
(build)
Generating b_lists
B INCLUDE_DIRECTORIES 1: D:/projects/cmakeminimal/.
B INCLUDE_DIRECTORIES 2: D:/projects/cmakeminimal/.;D:/libs/boost-1_55_0/include/boost-1_55
B LINK_LIBRARIES 1: A
B LINK_LIBRARIES 2: A

递归遍历LINK_LIBRARY财产是可能的。

这里有一个get_link_libraries()这样做可以做到这一点,但是它不能处理所有情况(例如,库不是目标,不是导入的库)。

function(get_link_libraries OUTPUT_LIST TARGET)
    get_target_property(IMPORTED ${TARGET} IMPORTED)
    list(APPEND VISITED_TARGETS ${TARGET})
    if (IMPORTED)
        get_target_property(LIBS ${TARGET} INTERFACE_LINK_LIBRARIES)
    else()
        get_target_property(LIBS ${TARGET} LINK_LIBRARIES)
    endif()
    set(LIB_FILES "")
    foreach(LIB ${LIBS})
        if (TARGET ${LIB})
            list(FIND VISITED_TARGETS ${LIB} VISITED)
            if (${VISITED} EQUAL -1)
                get_target_property(LIB_FILE ${LIB} LOCATION)
                get_link_libraries(LINK_LIB_FILES ${LIB})
                list(APPEND LIB_FILES ${LIB_FILE} ${LINK_LIB_FILES})
            endif()
        endif()
    endforeach()
    set(VISITED_TARGETS ${VISITED_TARGETS} PARENT_SCOPE)
    set(${OUTPUT_LIST} ${LIB_FILES} PARENT_SCOPE)
endfunction()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMake 中 LINK_LIBRARIES 的递归列表 的相关文章

  • 在生成器表达式中使用 cmake 选项

    我想在生成器表达式中使用 cmake 选项 为了打开某个编译标志 来自文档 https cmake org cmake help v3 10 manual cmake generator expressions 7 html我不清楚如何实现
  • 如何使我的单元测试适应 cmake 和 ctest?

    到目前为止 我已经使用了一个临时的单元测试程序 基本上是由批处理文件自动运行的全部单元测试程序 尽管其中很多都明确地检查了他们的结果 但还有更多的作弊行为 他们将结果转储到版本控制的文本文件中 测试结果中的任何更改都会被颠覆标记 我可以轻松
  • 如何使用 CMake 安装文件层次结构?

    我使用以下方法创建了文件列表 file GLOB RECURSE DEPLOY FILES PROJECT SOURCE DIR install 我想将所有这些文件安装在 usr myproject 但我想维护已安装文件夹上的文件树 ins
  • 为什么 cmake 在 git commit 后编译所有内容

    假设我有时在 Linux 上使用 cmake 2 8 编译一段代码 我更改了一个文件 my changed file 运行 cmake 并且只构建了这个文件 到目前为止 一切都很好 现在我想提交这个 git add my changed f
  • Clang 与 CLion:无法获取编译器信息

    我尝试通过更改在 CLion 中从 gcc 切换到 clang工具链偏爱 但现在 cmake 失败并显示以下内容 Cannot get compiler information Compiler exited with error code
  • 如何将最新的 Windows SDK 版本传递给 CMake?

    如何将最新的 Windows SDK 版本传递给 CMake 这样我就不需要进入 Visual Studio 并从配置属性 常规中手动放置它 我在互联网上搜索 找到了 CMAKE SYSTEM VERSION 变量 并且尝试使用 set C
  • 如何在Linux上构建GLFW3项目?

    我已经使用 cmake 和 make 编译了 glfw3 和包含的示例 没有出现任何问题 开始编写我的第一个项目 作为 opengl 和 glfw 的新手 并且对 C 和 CMake 没有经验 我正在努力理解示例构建文件 甚至要链接哪些库和
  • CMake:从多行文本文件获取版本

    我有一个文件version txt VERSION MAJOR 1 VERSION MINOR 1 VERSION PATCH 3 我想使用 cmake 添加主要 次要和补丁的定义 我尝试过使用 file STRING version tx
  • 如何告诉 CMake 将构建文件放在哪里?

    我想告诉 CMake 将文件和文件夹输出到不同的文件夹而不是当前文件夹 我在下面讨论的是 CMake 生成的文件 文件 CMakeCache txt 目录 CMakeFiles 文件 生成文件 目录 bin 文件 cmake install
  • CMake - 未定义参考

    我正在尝试将 gtest 包含到我的项目中 问题是我在 GTest 中收到未定义的引用错误 我正在尝试在 Gtest 中测试 Node 类 在节点的构造函数中 我使用类记录器 尽管我已将库记录器添加到 gtest target 中 但我仍然
  • Opencv - 找不到头文件

    我正在尝试使用 opencv 开始开发 问题是 到目前为止我几乎无法设置 opencv 因为我找不到它的头文件 我对此主题进行了一些研究 但没有一个真正有帮助 下面是一些链接 opencv2 包含文件在哪里 https stackoverf
  • 使用 CMake 编译时更改头文件位置会导致缺少 vtable 错误

    对于一个大型 C 项目 我需要从 qmake 过渡到 CMake 但是在处理一个玩具示例时 我遇到了一些我不理解的行为 示例代码具有单个头文件 当该头文件移动到子目录中时 我收到 MainWindow 类缺少 vtable 的错误 CMak
  • 如何使用cmake自动构建第三方库

    我在寻找什么 下载库 提取它 应用自定义补丁 运行配置 运行构建命令 我正在尝试构建的库是 Openssl Boost Thrift C ares Curl Pcre Nginx ICU JsonCPP 我想我可以使用外部模块做这些事情 h
  • CMake GUI:指定 Windows 的库路径

    我正在编译一个基于 CMake 的项目 具体来说是 SOCI 它依赖于 SQLite 这是Windows 没有可供项目研究的标准路径 因此它找不到SQLite 我在配置时得到这个 SQLite3 not found some librari
  • CMake:Fortran 模块和编译顺序

    我有一个大型 Fortran 程序 其中包含许多目录 每个目录都在伪库中单独编译 但仍然存在相互依赖的混乱 因此最终所有伪库都组合在一个可用的库中 我想使用 Fortran 模块 但它非常脆弱 因为我不能依赖自动依赖项检查 并且根据顺序编译
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • CMake AUTOMOC,文件位于不同文件夹中

    我有一个简单的 CMake 项目 proj project folder a h a cpp CMakeLists txt CMakeLists txt cmake minimum required VERSION 3 2 set CMAK
  • Visual Studio 2022 CMake 预设

    我在我的项目中使用 CMake 并开始探索 CMakePresets 的可能性 我设法创建了一个默认的 Windows 预设 目前我的 Windows 默认预设将 CMAKE BUILD TYPE 设置为调试 现在我想在左侧下拉列表中选择配
  • 通过 cmake 链接作为外部项目包含的 opencv 库[重复]

    这个问题在这里已经有答案了 我对 cmake 比较陌生 经过几天的努力无法弄清楚以下事情 我有一个依赖于 opencv 的项目 它本身就是一个 cmake 项目 我想静态链接 opencv 库 我正在做的是我的项目中有一份 opencv 源
  • Cmake 链接共享库:包含库中的头文件时“没有这样的文件或目录”

    我正在学习使用 CMake 构建库 构建库的代码结构如下 include Test hpp ITest hpp interface src Test cpp ITest cpp 在 CMakeLists txt 中 我用来构建库的句子是 f

随机推荐

  • 用于从字段中查找最大值的 MongoTemplate 方法或查询

    我正在使用 MongoTemplate 进行数据库操作 现在我想从所选结果中获取最大字段值 有人可以指导我如何编写查询 以便当我将查询传递给 find 方法时 它将返回我所需的文档最大字段 提前致谢 问候 可以在spring data mo
  • 如何获取 Azure Active Directory 登录用户的密码策略

    我想使用 graph api 或 adal 获取 C 中登录用户的密码到期日期 有了这个问题 我知道如何使用 PowerShell 获取密码策略以及到期日期 但还不确定如何使用 C 在 PowerShell 中获取 Azure Active
  • 切片 Dataframe 时出现 KeyError

    我的代码如下所示 d pd read csv Collector Output csv df pd DataFrame data d dfa df copy dfa dfa rename columns OBJECTID Object ID
  • 在 Yii 的标准中如何获得计数 (*)

    我正在尝试构建一个具有以下内容的查询group by属性 我正在尝试得到id和count它一直告诉我count is invalid列名 我怎样才能得到count来自group by询问 工作有别名 伊伊 1 1 11 其他不及格 crit
  • 如何将音乐从我的应用程序切换到 iPod

    我在用MusicPlayerController我的应用程序中的对象来播放音乐 我知道当 iPhone ipod 应用程序终止时 可以继续播放我的应用程序音乐 我该怎么做 这涉及到一些事情 您必须在两种音乐播放器之间进行选择 应用程序音乐播
  • 将表值参数与 SQL Server JDBC 结合使用

    任何人都可以提供一些有关如何将表值参数 TVP 与 SQL Server JDBC 一起使用的指导吗 我使用的是微软提供的6 0版本的SQL Server驱动程序 我已经查看了官方文档 https msdn microsoft com en
  • 对于某些纹理尺寸,glFramebufferTexture2D 在 iPhone 上失败

    当我尝试将纹理附加到帧缓冲区时 glCheckFramebufferStatus 报告某些纹理大小的 GL FRAMEBUFFER UNSUPPORTED 我已经在第二代和第四代 iPod Touch 上进行了测试 两个模型之间失败的纹理尺
  • 检查 touchend 是否在拖动后出现

    我有一些代码可以更改表的类 在手机上 有时表格对于屏幕来说太宽 用户将拖动 滚动来查看内容 但是 当他们触摸并拖动表格时 每次拖动都会触发 touchend 如何测试触摸端是否是触摸拖动的结果 我尝试跟踪dragstart和dragend
  • 如何在没有 web.xml 的情况下将 Struts2 添加到 Web 应用程序?

    有人可以帮助我使用 Spring Boot 和 Struts2 进行最小项目设置吗 我已经使用 H2 数据库创建了一个 Spring Boot 应用程序 我还添加了一个h2Configuration类 以便我能够访问数据库localhost
  • [A-z0-9]+ 正则表达式匹配方括号[重复]

    这个问题在这里已经有答案了 我正在努力解决以下正则表达式 A z0 9 如果针对此字符串进行测试 a919238 a asd 它返回a919238 包括方括号 我尝试输入我在 regex101 上的测试用例 https www regex1
  • 分叉/多线程进程|重击

    我想让我的代码的一部分更加高效 我正在考虑让它分叉成多个进程 并让它们一次执行 50 100 次 而不是只执行一次 例如 伪 for line in file do foo foo2 foo3 done 我希望这个 for 循环运行多次 我
  • 如何证明 .NET CLR JIT 每次运行只编译每个方法一次?

    There s 一个老问题 https stackoverflow com questions 1255803 does the net clr jit compile every method every time 1255832每次询问
  • 在 WPF 中使用 Datagrid 进行多重选择

    我想知道如何使用 DataGridCheckBoxColumn 选择多行 这里我只能选择一行 但如何进行多项选择 我的 XAML 如下
  • 如何持续更新MPAndroidChart中的Y轴值

    我希望 LineChart 中的轴能够实时调整其最大值和最小值 当新数据的 Y 值增加 正值和负值 时 像 ResetAxisMaxValue 和 ResetAxisMinValue 这样的函数可以很好地工作 但是 一旦信号再次变低 Y 值
  • matlab 中的动画绘图

    我正在尝试创建一个三角形的动画图 最终结果应该是十个三角形 后面跟着两个更大的三角形 后面跟着一条直线 使用matlab文档 https de mathworks com help matlab ref drawnow html 我最终得到
  • jquery window.open 在 ajax 成功中被阻止

    尝试在我的 ajax 成功调用中打开一个新的浏览器窗口 但是 它被阻止为弹出窗口 我做了一些搜索 发现用户事件需要绑定到 window open 才能避免这种情况发生 我还找到了这个解决方案 您可以在 ajax 之前打开一个空白窗口 然后在
  • 防止用户在下拉菜单中选择默认值

    我试图阻止用户选择默认的下拉菜单选项 有没有办法在下拉菜单选项中添加文本而不是值 我的代码
  • iPhone - 如何在矩形中间绘制文本

    有没有一种方法可以在矩形中间绘制文本 我可以找到各种对齐方式 但我尝试过的任何方法都不能将文本垂直居中在矩形中 有没有一种简单的方法可以做到这一点 或者有什么方法可以将矩形居中然后在其中绘制 我直接绘制到 CGContext 尝试使用 NS
  • 如何阻止gridview列自动编码html实体

    我对 ASP NET 相当陌生 在使用 gridview 时遇到了问题 我添加了一些包含 符号的条目 例如 PR Murphy Associates 在将数据插入数据库之前 我没有对数据进行任何编码 当网格视图更改为编辑模式时 我的文本如下
  • CMake 中 LINK_LIBRARIES 的递归列表

    我正在尝试获取链接到 CMake 中特定目标的所有库的绝对路径列表 以便在调用中使用add custom command 然而 get target property LINK LIBRARIES TARGET LINK LIBRARIES