CMake将共享库链接到静态库

时间:2015-07-19 16:53:44

标签: c++ c cmake

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

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

(与平台无关的方式)

4 个答案:

答案 0 :(得分:4)

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

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

add_library(staticfoo OBJECT <src>)

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

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

有关详细信息,请参阅documentation on add_library

答案 1 :(得分:2)

要解决此问题,您需要做一些事情:

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

答案 2 :(得分:1)

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

它显示了两个&#34;静态&#34;库,一个有两个可见符号,两者都有默认隐藏符号,被添加到共享库中,然后用于链接可执行文件。

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

唯一的非平台特定事物(我认为)是使用的__EXPORT宏。如果有人知道如何解决这个问题也很好。

答案 3 :(得分:1)

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