将两个静态库组合为一个动态库,同时避免多个定义



注意:这不是一个重复的问题,因为没有其他答案考虑到多个定义挑战。

我正在尝试将两个静态库合并为一个。(这是)。

然后将该静态库转换为动态库。(由于多重定义错误,此操作无法工作)。

我已经用示例源代码做了一个公共repo。

以下是关键组件:

return_zero.cpp

int return_zero() { return 0; }
int version() { return 0; }

return_one.cpp

int return_one() { return 1; }
int version() { return 1; }

注意每个库都有自己的version函数。

我可以将它们构建到它们自己的静态库中。libreturn_zero.alibreturn_one.a.

我可以将它们与ar实用程序组合成libreturn.a

当我使用nm实用程序转储符号时:

$ nm -C libreturn.a 
return_one.cpp.o:
0000000000000000 T return_one()
000000000000000b T version()
return_zero.cpp.o:
0000000000000000 T return_zero()
000000000000000b T version()

接下来,我尝试将这个聚合静态库转换为共享库。

我使用一个虚拟源文件,并使用--whole-archive链接标志链接libreturn.a

链接命令如下:

g++ -fPIC -shared -Wl,-soname,libreturn.so -o libreturn.so "dummy.cpp.o" -Wl,--push-state,--whole-archive libreturn.a -Wl,--pop-state

上面看起来是我想要的,但是它失败了,因为version有两个定义。

libreturn.a(return_zero.cpp.o): In function `version()':
return_zero.cpp:(.text+0xb): multiple definition of `version()'
libreturn.a(return_one.cpp.o):return_one.cpp:(.text+0xb): first defined here
collect2: error: ld returned 1 exit status
CMakeFiles/return-shared.dir/build.make:97: recipe for target 'libreturn.so' failed
make[2]: *** [libreturn.so] Error 1

我认为通过将两个静态库合并为一个静态库,归档器将删除多余的符号。

我如何去合并静态库到一个共享库时,有一个机会的符号名称冲突?

如果代码同时调用return_one()return_zero(),则不能使用聚合静态库,因为version()函数会出现重复的符号问题。

如果你链接到聚合库,你将如何决定你想要调用哪个version()函数?

你将不得不解决这个问题-这可能意味着像前缀return_zero.cpp中的所有函数,如r0_(或者,在c++中,将它们放在namespace return_zero { … }中),并且-为了对称,如果没有更好的理由-前缀return_one.cpp中的所有函数,如r1_(或将它们放在namespace return_one { … }中)。然后,调用代码将使用前缀名称(或者用适当的名称空间名称作为函数的前缀)。

相关内容

  • 没有找到相关文章