【问题标题】:CMake `INSTALL` for targets and its SO dependencies用于目标及其 SO 依赖项的 CMake `INSTALL`
【发布时间】:2018-08-30 13:19:00
【问题描述】:

我的目标使用TARGET_LINK_LIBRARIESPUBLIC 关键字与几个库链接,INSTALL 命令看起来像INSTALL(TARGETS foo DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)。我想以某种方式强制 cmake 包含我链接的所有(最好不包括系统库)库(仅限 SO),以包含在安装过程中。我试过 EXPORT 关键字,但看起来它只影响我在项目中构建的库,并用与 foo 库相同的 EXPORT 标记。
有可能吗?
EDIT001:可能影响答案的附加信息。 我正在使用vcpkg 来管理第三方。所以TARGET_LINK_LIBRARIES 看起来像

TARGET_LINK_LIBRARIES(foo PUBLIC
                      GTest::GTest
                      GTest::Main
                      ${GOOGLE_MOCK}
                      event
                      ${THRIFT_LIBRARIES}
                      ${Boost_LIBRARIES}
                      lzo2
                      sqlite3
                      ${ZeroMQ_LIBRARY}
                      gRPC::grpc
                      gRPC::grpc++
                      xml2
                      stdc++fs
                      bfd
                      -l:libisal.so.2
                      sgutils2
                      pthread
                      uuid
                      rt
                      )

所以,基本上我想要实现的是获取所有这些由vcpkg 宏化的库,例如${THRIFT_LIBRARIES}, ${Boost_LIBRARIES} and gRPC::grpc 等等

【问题讨论】:

  • 您需要列出您需要单独安装的所有内容。 AFAIK,CMake 不会进行任何会自动安装所有依赖项的分析。此外,您只有一个目标:foo 和命令 install targets。当然,还有其他安装命令,但它们也不接近TARGET_LINK_LIBRARIES 命令。
  • 如果没有其他选项听起来足够好,另一个问题是,我可以访问通过target_link_libraries 添加的所有依赖项,因为它们生成到make 文件中,因为它已经具有指向所以

标签: c++ cmake vcpkg


【解决方案1】:

从 cmake 3.21 开始,您现在可以使用:

install(IMPORTED_RUNTIME_ARTIFACTS gRPC::grpc)
install(IMPORTED_RUNTIME_ARTIFACTS ${Boost_LIBRARIES})

等等

new Install command

【讨论】:

  • 我尝试使用 spdlog 执行此操作,方法是:install(IMPORTED_RUNTIME_ARTIFACTS spdlog::spdlog),但是,我收到消息:“安装 IMPORTED_RUNTIME_ARTIFACTS 给定目标“spdlog::spdlog”,它不是可执行文件,库,或模块。”就像我使用 vcpkg 和使用 find_package 导入 spdlog 的 OP 一样。有什么想法吗?
  • @anthony-calandra:我对 spdlog 不熟悉,但对它进行“apt search”表示它是一个仅包含标头的库。因此,您不需要安装任何运行时工件。
  • 我认为他们正在解决你提到的这个错误@Antony Calandra。 gitlab.kitware.com/cmake/cmake/-/issues/22406他们写的时候没有预料到人们会以这种方式使用它。但用户不这么认为。简而言之:cmake 不知道 lib 是 .so 还是 .a。
【解决方案2】:

CMake 本身不允许自动安装依赖项。这将是一项相当艰巨的任务,因为它必须考虑很多极端情况。

想想传递依赖(我不知道这是不是正确的词),比如:你的libA 依赖于libB,它依赖于libC。 CMake 应该如何从仅列出 libB 的 CMakeLists 中获取此信息?

或者:您认为系统库是什么?所有不在PATH 中的东西?您如何知道客户端计算机上系统范围内安装了哪些库?

你看,有一些非常棘手的事情需要考虑。

您有以下几种可能性:

  • 请您的用户安装依赖项。
  • 将库静态链接到您的二进制文件中。
  • 使用install(FILES files... DESTINATION <dir>) 复制库文件。也许您的依赖管理器可以帮助创建文件列表。
  • 为 Windows 上基于 Qt 的应用程序编写类似 windeployqt 的脚本:分析二进制文件(例如使用 ldd myApp)并自动复制所需的依赖项。

【讨论】:

  • 您对极端案例的看法绝对正确,但您的第三条指出了重点,给我我的图书馆链接的东西的清单,我会从这个清单中挑选任何需要的东西。不幸的是,我没有找到获得上述列表的方法
猜你喜欢
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
  • 2021-08-19
相关资源
最近更新 更多