链接一个共享库到静态库
CMake link a shared library to static libraries
我正在将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/
- 那么,你需要在编译所有库时控制符号的可见性,所以作为共享库的一部分,来自静态库的符号将是可见的
- 最后,是的,您需要在链接共享库时指定
PRIVATE <static libs>
,因此您的可执行文件的链接器命令行不会有任何静态库
-fPIC
,所以他们将包含一个可重定位的代码(这将是一个共享库的一部分)请看我的回答。将/WHOLEARCHIVE
, -all_load
或--whole-archive
添加到链接器标志
我在这里创建了一个小示例,以正确的方式做到这一点:https://github.com/CarloWood/cmaketest
它展示了如何将两个"静态"库,一个带有两个可见符号,两个默认带有隐藏符号,添加到共享库中,然后用于链接可执行文件。
使用的方法是@Tsyvarev的方法,结合@Zaufi提到的VISIBILITY target属性。
唯一非平台特定的东西(我认为)是__EXPORT宏所使用的。
相关文章:
- 将静态库链接到不带-fPIC的共享库中
- C++两个源文件之间共享的枚举的静态实例
- 内联函数的函数本地静态对象是否在共享对象文件之间共享?
- Android NDK:用于第三方Java库的静态或共享C++运行时
- 仅在少数方法(静态或共享库)中解析的外部符号
- c++ 是否保证标头初始化的静态 const 成员跨编译单元和库共享单个实例?
- 函数范围的静态变量如何导致与共享库中函数代码的未来使用不兼容
- 如何在共享库中保留静态库中的自由函数
- Cmake 查找模块用于区分共享库或静态库
- 指向静态常量对象的共享指针?
- 从静态库构建共享库
- c++ 防止类共享静态对象
- 跨共享/静态库集成C++自定义内存分配器
- 混合共享/静态库时静态成员的多个副本
- 在动态库之间共享静态库中的数据
- Python C 接口,不同的模块共享静态变量
- 在多个解决方案之间共享C++静态库会导致不必要的重建
- 在同一DLL的实例之间共享静态和全局变量
- 跨dll共享静态模板数据
- Xcode不与共享库共享静态变量