我在 ubuntu 上构建了一个 C++ 程序和一个共享库(mylib.so)。
如果我在 ubuntu 22 (gcc 11.4.0) 上构建并运行程序,一切都很好。 如果我尝试在 ubuntu 24 上运行相同的二进制文件,则无法加载 mylib.so。
使用 LD_DEBUG 检查发现:
ldout.txt.12101: 12101: mylib.so: error: symbol lookup error: undefined symbol:
_TIFFwarningHandler (fatal)
_TIFFwarningHandler 是来自 libtiff 的符号,它是 mylib.so 的一部分,并从完整源代码构建 - 无需额外的库。这怎么能被视为外部符号呢?
如果我现在在 ubuntu 24 (gcc 13.2.0) 上构建相同的程序,它将按预期工作和运行。 只需替换 mylib.so 就足够了 - 然后在 ubuntu 22 上创建的可执行文件可以在 ubuntu 24 上运行。
有人可以解释这种行为吗? 我怎样才能从 ubuntu 22 获得构建并在 ubuntu 24 上运行?
两个.so文件的区别是:
ubuntu 22:
nm bin/mylib.so | grep -i _TIFFwarningHandler
U _TIFFwarningHandler
0000000000253920 B _TIFFwarningHandlerExt
ubuntu 24:
nm bin/myLib.so | grep -i _TIFFwarningHandler
000000000023f480 D _TIFFwarningHandler
000000000024b918 B _TIFFwarningHandlerExt
使用 ubuntu 22 构建时,TIFFwarningHandler 未定义。 但用 ubuntu 24 编译时就不行了。
但是在 ubuntu 22 中这个符号可以在 libtiff.so.5 中找到:
binding file /usr/lib/x86_64-linux-gnu/libtiff.so.5 [0] to /usr/lib/x86_64-linux-gnu/libtiff.so.5 [0]: normal symbol `_TIFFwarningHandlerExt' [LIBTIFF_4.0]
在 ubuntu 22 中 libtiff.so.5 不再存在 - 而是使用 libtiff.so.6。并且这不会导出 _TIFFwarningHandler
symbol=_TIFFwarningHandler; lookup in file=/usr/lib/x86_64-linux-gnu/libtiff.so.6 [0]
...
myLib.so: error: symbol lookup error: undefined symbol: _TIFFwarningHandler (fatal)