I am porting an AutoTools project to CMake.
我正在向CMake移植一个AutoTools项目。
What AutoTools does:
什么AutoTools:
- builds some static libraries
- 建立一些静态库
- builds some shared libraries and links static ones into shared
- 构建一些共享库并将静态库链接到共享库中
- builds an executable, links it to shared libraries
- 构建可执行文件,将其链接到共享库。
What I've managed to do with CMake:
我用CMake做了什么:
- build some static libraries -
add_library(staticfoo <src>)
-
构建一些静态库- add_library(staticfoo
) - build some shared libraries -
add_library(sharedfoo SHARED <src>)
and link them -target_link_libraries(sharedfoo staticfoo)
-
构建一些共享库—add_library(sharedfoo共享
)并链接它们—target_link_libraries(sharedfoo staticfoo) - build an executable, link it to shared libraries -
target_link_libraries(exe sharedfoo)
, but that dragged the static libraries in again, too. - 构建一个可执行文件,将它链接到共享库——target_link_libraries(exe sharedfoo),但这也将静态库拖了进来。
So, the resulting link command for the executable has static libs in addition to shared. Which doesn't correspond to the command generated by AutoTools project.
因此,可执行文件的结果链接命令除了共享之外还有静态的lib。这与AutoTools项目生成的命令不一致。
I've tried target_link_libraries(sharedfoo PRIVATE staticfoo)
, but that doesn't get the symbols from the static lib into the interface of the shared lib.
我尝试过target_link_libraries(sharedfoo PRIVATE staticfoo),但它并没有将静态库中的符号获取到共享库的接口中。
How to get the symbols without that 'transitive' behavior?
如何获得符号而没有“传递”行为?
(in platform-independent way)
(以独立于平台的方式)
4 个解决方案
#1
3
As I know, CMake doesn't allow to mix STATIC and SHARED libraries.
正如我所知道的,CMake不允许混合静态库和共享库。
If your staticfoo
library is used solely as part of other libraries/executables, you can define it as
如果您的staticfoo库仅作为其他库/可执行文件的一部分使用,您可以将其定义为
add_library(staticfoo OBJECT <src>)
and use then as some sort of sources when build other library:
然后在建立其他图书馆的时候使用一些资源:
add_library(sharedfoo SHARED <src> $<TARGET_OBJECTS:staticfoo>)
For more info see documentation on add_library.
要了解更多信息,请参阅add_library的文档。
#2
2
To resolve this case you need to do few things:
要解决这个问题,你需要做一些事情:
- first of all make sure you've compiled static libraries w/
-fPIC
, so they'll contain a relocatable code (which would be a part of a shared library later) - 首先,确保您已经编译了静态库w/ -fPIC,因此它们将包含可重定位的代码(稍后将成为共享库的一部分)
- then, you need to control symbols visibility when compiling all libraries, so being a part of shared library, symbols came from the static one would be visible
- 然后,在编译所有库时需要控制符号的可见性,因此作为共享库的一部分,来自静态库的符号是可见的
- and finally, yes, you need to specify
PRIVATE <static libs>
when linking your shared library, so the linker command line for your executable wouldn't have any static libs -
最后,是的,在链接共享库时需要指定PRIVATE
,这样可执行文件的链接器命令行就不会有任何静态libs
#3
1
I created a little example that does this the right way, here: https://github.com/CarloWood/cmaketest
我创建了一个用正确的方式实现这一点的示例:https://github.com/CarloWood/cmaketest
It shows how two "static" libraries, one with two visible symbols, both with by default hidden symbols, are added to a shared library, which is then used to link an executable.
它展示了如何向共享库中添加两个“静态”库,其中一个带有两个可见符号(都带有默认的隐藏符号),然后用于链接可执行文件。
The method used is that of @Tsyvarev, combined with the VISIBILITY target property mentioned by @Zaufi.
使用的方法是@Tsyvarev,结合@Zaufi提到的可见性目标属性。
The only non-platform specific thing (I think) is the __EXPORT macro that is used. It would be nice to fix that too, if anyone knows how.
唯一非平台特定的东西(我认为)是使用的__EXPORT宏。如果有人知道该怎么做的话,最好也能解决这个问题。
#4
0
See my answer here. Basically add /WHOLEARCHIVE
, -all_load
, or --whole-archive
to the linker flags.
看到我的答案。基本上是向链接器标志添加/WHOLEARCHIVE、-all_load或-全归档。
#1
3
As I know, CMake doesn't allow to mix STATIC and SHARED libraries.
正如我所知道的,CMake不允许混合静态库和共享库。
If your staticfoo
library is used solely as part of other libraries/executables, you can define it as
如果您的staticfoo库仅作为其他库/可执行文件的一部分使用,您可以将其定义为
add_library(staticfoo OBJECT <src>)
and use then as some sort of sources when build other library:
然后在建立其他图书馆的时候使用一些资源:
add_library(sharedfoo SHARED <src> $<TARGET_OBJECTS:staticfoo>)
For more info see documentation on add_library.
要了解更多信息,请参阅add_library的文档。
#2
2
To resolve this case you need to do few things:
要解决这个问题,你需要做一些事情:
- first of all make sure you've compiled static libraries w/
-fPIC
, so they'll contain a relocatable code (which would be a part of a shared library later) - 首先,确保您已经编译了静态库w/ -fPIC,因此它们将包含可重定位的代码(稍后将成为共享库的一部分)
- then, you need to control symbols visibility when compiling all libraries, so being a part of shared library, symbols came from the static one would be visible
- 然后,在编译所有库时需要控制符号的可见性,因此作为共享库的一部分,来自静态库的符号是可见的
- and finally, yes, you need to specify
PRIVATE <static libs>
when linking your shared library, so the linker command line for your executable wouldn't have any static libs -
最后,是的,在链接共享库时需要指定PRIVATE
,这样可执行文件的链接器命令行就不会有任何静态libs
#3
1
I created a little example that does this the right way, here: https://github.com/CarloWood/cmaketest
我创建了一个用正确的方式实现这一点的示例:https://github.com/CarloWood/cmaketest
It shows how two "static" libraries, one with two visible symbols, both with by default hidden symbols, are added to a shared library, which is then used to link an executable.
它展示了如何向共享库中添加两个“静态”库,其中一个带有两个可见符号(都带有默认的隐藏符号),然后用于链接可执行文件。
The method used is that of @Tsyvarev, combined with the VISIBILITY target property mentioned by @Zaufi.
使用的方法是@Tsyvarev,结合@Zaufi提到的可见性目标属性。
The only non-platform specific thing (I think) is the __EXPORT macro that is used. It would be nice to fix that too, if anyone knows how.
唯一非平台特定的东西(我认为)是使用的__EXPORT宏。如果有人知道该怎么做的话,最好也能解决这个问题。
#4
0
See my answer here. Basically add /WHOLEARCHIVE
, -all_load
, or --whole-archive
to the linker flags.
看到我的答案。基本上是向链接器标志添加/WHOLEARCHIVE、-all_load或-全归档。