CMake将共享库链接到静态库
我将一个AutoTools项目移植到CMake。CMake将共享库链接到静态库
自动工具的作用:
- 建立一些静态库
- 建立一些共享库和静态的链接到共享
- 建立一个可执行文件,它链接到共享库
什么我设法做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的不允许混用静态和共享库。
如果您staticfoo
库仅用作其他库/可执行文件的一部分,你可以将它定义为
add_library(staticfoo OBJECT <src>)
,然后使用作为某种形式的来源时构建其他库:
add_library(sharedfoo SHARED <src> $<TARGET_OBJECTS:staticfoo>)
欲了解更多信息,请参阅documentation on add_library。
要解决这种情况下,你需要做的几件事情:
- 首先,确保你已经编译静态库W/
-fPIC
,所以他们会包含一个重定位代码(这将是一个部分以后,你需要在编译所有库时控制符号的可见性,所以作为共享库的一部分,符号来自静态的将会是可见的 - 最后,是的,你需要链接您的共享库时指定
PRIVATE <static libs>
,因此执行程序的链接器命令行表不会有任何静态库
因此,如何'控制符号可见度'? – Velkan
最明显的方法是使用'-fvisibility' [编译器选项](https://gcc.gnu.org/wiki/Visibility)。 CMake> = 3.x具有['CMAKE_
我创建了一个小例子,这不正确的方式,在这里:https://github.com/CarloWood/cmaketest
它显示了两个“静态”库,一个有两个明显的符号,都与默认情况下,隐藏的符号被添加到共享库,然后用于链接可执行文件。
使用的方法是@Tsyvarev,与@Zaufi提到的VISIBILITY目标属性相结合。
唯一的非平台特定的事情(我认为)是使用__EXPORT宏。如果有人知道如何解决,那也是很好的。
CMake不关心你试图链接静态/动态/混合的类型的库......这将成为特定平台链接器的问题。 – zaufi
在窗口上,链接器通过链接已保存的对象/静态库来丢弃导出符号,但解压缩的对象可以工作。这是为什么将对象库添加到cmake中的主要原因之一。 – Youka
事实上,这是转换自动工具项目中找到的模式的好方法。对于替代品和他们的问题,看到这个详细的问题:http://stackoverflow.com/questions/5136184/linking-windows-dll-files-from-static-libraries-using-cmake-without-hand-craftin –