共享库中奇怪的未定义符号行为

问题描述 投票:0回答:1

我在共享库中遇到了一个奇怪的未定义符号的情况,我无法解决。假设我的程序需要使用一个库

A
,而该库又依赖于另一个库
B
,这两个库我都无法修改。

我首先使用他们自己的 automake 系统构建库

B
,该系统创建静态
libB.a
libB.so
库。静态库
libB.a
包含一些重复的损坏符号,这些符号源自不同的目标文件,其中一些是未定义的。这对我来说似乎很正常。共享库
libB.so
仅包含每个符号的一个版本,其中没有一个是未定义的。

然后我再次使用他们自己的构建系统构建库

A
(这次不是automake,而是一些写得不好的makefile)。概括地说,A 的构建系统所做的就是

g++ -shared -fPIC -DPIC -std=c++17 -fPIC -fopenmp -I<path/to/includes> -Wl,-rpath,<path/to/libs> -L<path/to/libs> -lB A.cc -o libA.so

我认为只是使用共享库

libA.so
构建
libB.so
。最终我的目标是将我的主程序链接到
libA.so

这就是我的问题开始的地方。我的主程序无法链接到

libA.so
并声称存在一些未定义的符号。使用
libA.so
查看
nm
表明它确实有一些未定义的符号,与静态
libB.a
中未定义的符号相同,尽管这次只显示了每个未定义符号的一个副本。此外,当我在
ldd
上运行
libA.so
时,它没有显示与
libB.so
的链接,这让我认为它正在使用库的静态版本。然而,作为测试,我在构建
libB.a
之后但在构建
B
之前删除了静态库
A
,同时保持共享库
libB.so
不变,但这并没有改变任何东西。

我还尝试创建

A
的静态版本并将我的主程序链接到该版本,但它遇到了同样的问题,现在未定义的符号链接错误变成了对 X 错误的未定义引用。

所以我的问题是:为什么在

libB.so
上运行
ldd
时不显示
libA.so
?为什么只有符号的未定义版本最终出现在
libA.so
中,即使我(据说)链接到
libB.so
,它没有未定义的符号?除了提供一些标志之外,我知道我无法更改
A
B
的 make 系统,我能做些什么来解决这个问题?预先感谢您的帮助。

编辑:我刚刚发现,如果我创建

A
的静态版本并将我的主程序链接到它 before 链接到
B
它会成功。但我不确定为什么。

shared-libraries undefined-symbol
1个回答
0
投票

所以我的问题是:为什么在 libA.so 上运行 ldd 时 libB.so 不显示?

请参阅此答案

除了提供一些标志之外,我无法更改 A 或 B 的 make 系统,我能做些什么来解决这个问题?

libA.so
链接命令更改为
... A.cc -o libA.so -lB
应该可以解决此问题。

© www.soinside.com 2019 - 2024. All rights reserved.