链接一个共享库到静态库

CMake link a shared library to static libraries

本文关键字:共享 静态 一个 链接      更新时间:2023-10-16

我正在将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),但这并没有从静态库中获得符号到共享库的接口。

如何获得没有"传递"行为的符号?

(与平台无关)

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

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

add_library(staticfoo OBJECT <src>)

并在构建其他库时将其用作某种源:

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

有关更多信息,请参阅add_library的文档

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

    首先确保你已经编译了静态库w/-fPIC,所以他们将包含一个可重定位的代码(这将是一个共享库的一部分)
  • 那么,你需要在编译所有库时控制符号的可见性,所以作为共享库的一部分,来自静态库的符号将是可见的
  • 最后,是的,您需要在链接共享库时指定PRIVATE <static libs>,因此您的可执行文件的链接器命令行不会有任何静态库

请看我的回答。将/WHOLEARCHIVE, -all_load--whole-archive添加到链接器标志

我在这里创建了一个小示例,以正确的方式做到这一点:https://github.com/CarloWood/cmaketest

它展示了如何将两个"静态"库,一个带有两个可见符号,两个默认带有隐藏符号,添加到共享库中,然后用于链接可执行文件。

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

唯一非平台特定的东西(我认为)是__EXPORT宏所使用的。

如果有人知道如何解决这个问题,那就太好了。