CMake - 如何使用 TARGET_RUNTIME_DLLS 处理导入库目标的依赖关系

发布于 2025-01-10 03:29:47 字数 1369 浏览 0 评论 0原文

在我的项目中,我依赖于一些名为 foo 的第三方共享库。

foo 本身依赖于其他一些第三方 dll(我们称之为 bar.dll),但是我的项目既没有使用它,也没有在 的标头中公开foo.

创建 foo 目标并链接到我的项目,如下所示

add_library(foo SHARED IMPORTED)
set_target_properties(foo PROPERTIES
  IMPORTED_LOCATION "${foo_dll_path}"
  IMPORTED_IMPLIB   "${foo_lib_path}"
)

target_link_libraries(my_project PUBLIC foo)

稍后,触发构建后事件,通过 $$生成器表达式。

如何在此设置中引入 bar.dll 以便在 $ 中可见?

到目前为止,我尝试通过 add_library(bar UNKNOWN IMPORTED)add_library(bar SHARED IMPORTED) 添加 bar.dll 作为另一个导入目标相应地在 bar 上设置 IMPORTED_LOCATION,但这确实会产生链接器错误。 示例:

add_library(bar UNKNOWN IMPORTED)
set_target_properties(bar PROPERTIES
  IMPORTED_LOCATION "${bar_dll_path}"
)
target_link_libraries(foo INTERFACE bar)

如果 UNKNOWN ,链接器将使用 bar.dll 作为链接器输入,这当然会失败,如果 SHARED IMPORTED CMake 要求IMPORTED_IMPLIB 已设置,但我既没有 bar.dll 的导入库,也不想链接 my_project

还有其他建议如何处理这个问题吗?

In my project I rely on some third party shared library named foo.

foo itself is relying on some other third party dll (let's call it bar.dll), which is however neither used by my project nor exposed in the headers of foo.

The foo target is created and linked to my project as follows

add_library(foo SHARED IMPORTED)
set_target_properties(foo PROPERTIES
  IMPORTED_LOCATION "${foo_dll_path}"
  IMPORTED_IMPLIB   "${foo_lib_path}"
)

target_link_libraries(my_project PUBLIC foo)

Later on a post build event is triggered to create hard links to all dependent 3rd party libraries via $<TARGET_RUNTIME_DLLS:my_project> generator expression.

How can bar.dll be introduced in this setup to be visible in $<TARGET_RUNTIME_DLLS:my_project>?

So far I tried to add bar.dll as yet another imported target via add_library(bar UNKNOWN IMPORTED) and add_library(bar SHARED IMPORTED) and setting IMPORTED_LOCATION on bar accordingly, which however does create linker errors.
Example:

add_library(bar UNKNOWN IMPORTED)
set_target_properties(bar PROPERTIES
  IMPORTED_LOCATION "${bar_dll_path}"
)
target_link_libraries(foo INTERFACE bar)

In case of UNKNOWN the linker will use bar.dll as linker input, which of course fails, in case of SHARED IMPORTED CMake demands that IMPORTED_IMPLIB is set, but neither do I have the import library for bar.dll nor do I want to link my_project against it.

Any other suggestions how to deal with this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如若梦似彩虹 2025-01-17 03:29:47

由于似乎这个问题没有适当的解决方案我提出了使用涉及元目标的(可能脆弱的)解决方法:

# same as before
add_library(foo_real SHARED IMPORTED)
set_target_properties(foo_real PROPERTIES
  IMPORTED_LOCATION "${foo_dll_path}"
  IMPORTED_IMPLIB   "${foo_lib_path}"
)

# add SHARED IMPORTED target with the importlib pointing to foo_reals importlib location
add_library(bar SHARED IMPORTED)
set_target_properties(bar PROPERTIES
  IMPORTED_LOCATION "${bar_dll_path}"
  IMPORTED_IMPLIB   "${foo_lib_path}" # same lib path as for imported target foo
)

# add meta target to combine both
add_library(foo INTERFACE IMPORTED)
target_link_libraries(foo INTERFACE foo_real bar)

# finally link the meta target to the final project
target_link_libraries(my_project PUBLIC foo)

此解决方法将导致 CMake 生成一个构建脚本,多次将 foo.lib 传递给链接器,这似乎不会导致当前 MSVC 出现问题工具集。此外,bar.dll 现在将按预期成为 TARGET_RUNTIME_DLLS 的一部分。

Since there seems to be no proper solution to this issue I came up with a (possibly fragile) workaround involving a meta target:

# same as before
add_library(foo_real SHARED IMPORTED)
set_target_properties(foo_real PROPERTIES
  IMPORTED_LOCATION "${foo_dll_path}"
  IMPORTED_IMPLIB   "${foo_lib_path}"
)

# add SHARED IMPORTED target with the importlib pointing to foo_reals importlib location
add_library(bar SHARED IMPORTED)
set_target_properties(bar PROPERTIES
  IMPORTED_LOCATION "${bar_dll_path}"
  IMPORTED_IMPLIB   "${foo_lib_path}" # same lib path as for imported target foo
)

# add meta target to combine both
add_library(foo INTERFACE IMPORTED)
target_link_libraries(foo INTERFACE foo_real bar)

# finally link the meta target to the final project
target_link_libraries(my_project PUBLIC foo)

This workaround will cause CMake to generate a build script passing foo.lib multiple times to the linker which does not seem to cause problems with the current MSVC Toolset. Also bar.dll will now be part of TARGET_RUNTIME_DLLS as intended.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文