【问题标题】:Archiving static dependencies in modern CMake project在现代 CMake 项目中归档静态依赖项
【发布时间】:2019-02-05 12:36:56
【问题描述】:

我需要打包一个链接到其他一些静态库的 C++ 库,并且我希望能够单独发送已编译的文件,而无需发送传递依赖项。为此,我关注this guide regarding modern CMake techniques,并将所有需要的依赖项指定为PRIVATE,因为它们没有在我的库的公开API 中使用。

问题在于,尽管已将依赖项指定为 PRIVATE,但链接器似乎仍未将它们包含在输出库中,因此如果我尝试将我的库链接到可执行文件,链接器会抱怨缺少符号(至少使用 MSVC)。有没有办法解决这个问题?

我已经查看了this,但我不确定如何将其集成到现有的 INSTALL 目标中

【问题讨论】:

  • 很可能您必须为不同的系统以不同的方式构建它。查看 gcc/clang 和 MSVCsolution。怀疑是否有更好的方法,因为组合静态库的愿望相当特殊,而 CMake 相当普遍。
  • 所以我基本上需要编写一个自定义构建脚本,对吗?我将无法依赖 cmake-install
  • 好吧,我不会称它为自定义脚本。这只是您可以在 CMake 中编写的一些直接命令。我也不认为 libs 组合是一个安装步骤。这只是另一个构建步骤,它依赖于其他库,但使用不同的命令来完成该步骤,仅此而已。
  • CPack 使用安装目标来创建包,所以我想重用它来达到目的。如果我对目标应用一些自定义命令,生成的配置文件仍然存在问题,因为它们会尝试解决传递依赖项
  • 这是静态库还是动态库? PRIVATE 链接仅控制 CMake 是否在目标之间传播链接要求。它不会影响链接本身 AFAIK。

标签: c++ cmake static dependencies


【解决方案1】:

假设您正在创建一个静态库:

您收到未解析的符号,因为静态库中的依赖项在创建期间未解析。只有当您将静态库链接到可执行文件或共享库时,链接器才会真正尝试解析所需的符号(在您的情况下会失败)。

因此,您需要将静态库组合成一个单独的库(正如您已经发现的那样)。

您应该遵循您链接到的答案中概述的 add_custom_commandadd_custom_target 的组合方法 (https://stackoverflow.com/a/32888999/1228449)。

然后使用INSTALL( FILES ....) 将组合库添加到您的安装命令中,例如:

include(GNUInstallDirs)
INSTALL( FILES ${LIBNAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} )

编辑: 或者,创建一个共享库。

ADD_LIBRARY( mylibrary SHARED ...)

然后在链接时解析私有静态库所需的符号。此外,只有您的库实际使用的符号才会集成到您的库中(而静态库将包含所有内容)。

【讨论】:

  • 我认为我将无法使用 CMakePackageConfigHelpers 对吗?我必须手动编写 mylib-config.cmake 文件,以避免它必须搜索现在包含的依赖项
猜你喜欢
  • 2012-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
相关资源
最近更新 更多