我在共享库中遇到了一个奇怪的未定义符号的情况,我无法解决。假设我的程序需要使用一个库
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
它会成功。但我不确定为什么。
所以我的问题是:为什么在 libA.so 上运行 ldd 时 libB.so 不显示?
请参阅此答案。
除了提供一些标志之外,我无法更改 A 或 B 的 make 系统,我能做些什么来解决这个问题?
将
libA.so
链接命令更改为 ... A.cc -o libA.so -lB
应该可以解决此问题。