【问题标题】:CMake link a shared library to static librariesCMake 将共享库链接到静态库
【发布时间】:2015-10-08 19:32:33
【问题描述】:

我正在将一个 AutoTools 项目移植到 CMake。

AutoTools 的作用:

  • 构建一些静态库
  • 构建一些共享库并将静态库链接到共享库中
  • 构建可执行文件,将其链接到共享库

我用 CMake 做了什么:

  • 构建一些静态库 - add_library(staticfoo <src>)
  • 构建一些共享库 - add_library(sharedfoo SHARED <src>) 并链接它们 - target_link_libraries(sharedfoo staticfoo)
  • 构建一个可执行文件,将其链接到共享库 - target_link_libraries(exe sharedfoo),但这也将静态库再次拖入。

因此,生成的可执行文件链接命令除了共享库之外还有静态库。这与 AutoTools 项目生成的命令不对应。

我尝试过target_link_libraries(sharedfoo PRIVATE staticfoo),但这并没有将静态库中的符号获取到共享库的接口中。

如何在没有“传递”行为的情况下获取符号?

(以独立于平台的方式)

【问题讨论】:

    标签: c++ c cmake


    【解决方案1】:

    据我所知,CMake 不允许混合使用 STATIC 和 SHARED 库。

    如果您的 staticfoo 库仅用作其他库/可执行文件的一部分,您可以将其定义为

    add_library(staticfoo OBJECT <src>)
    

    然后在构建其他库时用作某种来源:

    add_library(sharedfoo SHARED <src> $<TARGET_OBJECTS:staticfoo>)
    

    欲了解更多信息,请参阅documentation on add_library

    【讨论】:

    • CMake 不在乎您尝试链接静态/动态/混合的库类型...这将是特定平台上的链接器的问题。
    • 在 Windows 上,链接器通过链接归档对象/静态库来丢弃导出符号,但解压对象可以工作。这就是将对象库添加到 cmake 的主要原因之一。
    • 确实,这是转换 autotools 项目中的模式的好方法。对于替代方案及其问题,请参阅这个详细的问题:stackoverflow.com/questions/5136184/…
    • 另外,我需要使用set_property(TARGET staticfoo PROPERTY POSITION_INDEPENDENT_CODE ON) 为静态库启用与位置无关的代码。见stackoverflow.com/questions/38296756/…
    【解决方案2】:

    要解决这种情况,您需要做几件事:

    • 首先确保您已使用 -fPIC 编译静态库,因此它们将包含可重定位代码(稍后将成为共享库的一部分)
    • 那么,您需要在编译所有库时控制符号的可见性,因此作为共享库的一部分,来自静态库的符号将是可见的
    • 最后,是的,您需要在链接共享库时指定 PRIVATE &lt;static libs&gt;,这样可执行文件的链接器命令行就不会包含任何静态库

    【讨论】:

    【解决方案3】:

    查看我的回答here。基本上将/WHOLEARCHIVE-all_load--whole-archive 添加到链接器标志中。

    【讨论】:

      【解决方案4】:

      我创建了一个以正确方式执行此操作的小示例,此处:https://github.com/CarloWood/cmaketest

      它显示了如何将两个“静态”库(一个具有两个可见符号,默认情况下都具有隐藏符号)添加到共享库,然后用于链接可执行文件。

      使用的方法是@Tsyvarev 的方法,结合@Zaufi 提到的VISIBILITY 目标属性。

      唯一与平台无关的东西(我认为)是使用的 __EXPORT 宏。如果有人知道如何解决,也可以解决这个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-09
        • 2016-12-06
        • 1970-01-01
        • 1970-01-01
        • 2020-12-17
        • 2020-04-27
        相关资源
        最近更新 更多