注意:这不是一个重复的问题,因为没有其他答案考虑到多个定义挑战。
我正在尝试将两个静态库合并为一个。(这是)。
然后将该静态库转换为动态库。(由于多重定义错误,此操作无法工作)。
我已经用示例源代码做了一个公共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.a
和libreturn_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 { … }
中)。然后,调用代码将使用前缀名称(或者用适当的名称空间名称作为函数的前缀)。