本文主要是介绍解决依赖库libunwind编译报错undefined reference to ‘lzma_stream_buffer_decode‘,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
问题背景
程序MyApp依赖第三方库libunwind,在A机器上编译好静态库libunwind.a之后,在B机器上基于libunwind.a编译MyApp。由于B机器上的lib环境与A机器上可能有差异,因此产生了编译报错。
错误信息
在编译MyApp时,链接libunwind静态库阶段,发生错误:undefined reference to ‘lzma_xx’:
MyApp/third_party/installed/lib/libunwind.a(elf64.o): In function `xz_uncompressed_size':
MyApp/third_party/src/libunwind/libunwind/src/elfxx.c:194: undefined reference to `lzma_stream_footer_decode'
MyApp/third_party/src/libunwind/libunwind/src/elfxx.c:201: undefined reference to `lzma_index_buffer_decode'
MyApp/third_party/src/libunwind/libunwind/src/elfxx.c:205: undefined reference to `lzma_index_size'
MyApp/third_party/src/libunwind/libunwind/src/elfxx.c:210: undefined reference to `lzma_index_end'
MyApp/third_party/src/libunwind/libunwind/src/elfxx.c:207: undefined reference to `lzma_index_uncompressed_size'
MyApp/third_party/src/libunwind/libunwind/src/elfxx.c:210: undefined reference to `lzma_index_end'
MyApp/third_party/installed/lib/libunwind.a(elf64.o): In function `_Uelf64_extract_minidebuginfo':
MyApp/third_party/src/libunwind/libunwind/src/elfxx.c:278: undefined reference to `lzma_stream_buffer_decode'
collect2: error: ld returned 1 exit status
src/tools/CMakeFiles/rocksdb_sst_dump.dir/build.make:154: recipe for target 'bin/rocksdb_sst_dump' failed
make[2]: *** [bin/rocksdb_sst_dump] Error 1
问题分析
编译报错问题有点奇怪,在C机器上是正常的,只在B机器上报错。另外libunwind本身已经是静态.a库,我们预期libunwind不会再依赖第三方库,但是在编译MyApp过程中链接libunwind时,还是报错依赖库liblzma找不到。
网上搜索问题,参考了能找到的各种链接:
- https://bugs.launchpad.net/ubuntu/+source/libunwind/+bug/1336912
- https://lore.kernel.org/all/1432040746-1755-3-git-send-email-adrian.hunter@intel.com/
- https://github.com/monero-project/monero/issues/866#issuecomment-227197274
- https://github.com/monero-project/monero/issues/907#issuecomment-232510599
- https://github.com/monero-project/monero/issues/1412
网上的说法有3种:有说依赖冲突的、有说缺少安装liblzma的、有说安装了liblzma但找不到名字的,因为都没有说明问题根源,所以只能尝试下各种解决方案。
经过定位,这个错误的原因找到了,因为A上安装了liblzma压缩库(/usr/lib/x86_64-linux-gnu/liblzma.a),B机器没有安装liblzma(系统库路径均查找不到),导致A机器上编译的libunwind在B机器环境中链接时找不到liblzma(使用cmake find_library验证也确实如此)。
问题的原因是B机器缺少安装liblzma,理论上在B机器上安装liblzma应该是能解决的,不过这种解决方法不太适用于B机器不具备在线网络安装的场景。此外还有一个现象是,有一个老版本的libunwind库在B机器上是能链接成功的(猜测老版本的libunwind应该不是在A机器上编译的),这也说明libunwind对liblzma的依赖应该不是必须的。
附命令:查看liblzma是否安装、是否在链接路径中:
sudo find / -name "*lzma*.a*"
ldconfig -p | grep lzma
附命令:cmake查找liblzma路径:
message(STATUS "looking for liblzma for libunwind")
find_library(LIBLZMA_LIBRARIES lzma)
if(NOT LIBLZMA_LIBRARIES STREQUAL "LIBLZMA_LIBRARIES-NOTFOUND")message(STATUS "liblzma is found")set(LIBUNWIND_LIBRARIES "${LIBUNWIND_LIBRARIES};${LIBLZMA_LIBRARIES}")include(FindPackageHandleStandardArgs)find_package_handle_standard_args(Libunwind "can not find libunwind" LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARIES)# show the LIBUNWIND_INCLUDE_DIR and LIBUNWIND_LIBRARIES variables only in the advanced viewmark_as_advanced(LIBUNWIND_INCLUDE_DIR LIBUNWIND_LIBRARIES)
else()message(WARNING "liblzma is not found")
endif()
解决方案
因此更加彻底的解决方案有如下选择:
- 方案1:当在机器A上编译第三方库libunwind时,明确禁止链接liblzma库。(此方案跟老版本的libunwind也保持兼容,猜测老版本的libunwind应该是在未安装liblzma的机器上编译的)
- 方案2:当在机器A上编译第三方库libunwind时,把liblzma库也纳入进来,显示编译liblzma为静态库并放入自己的MyApp目录中。
为了跟老版本保持兼容,优先尝试方案1。接下来寻找如何去明确禁止libunwind链接liblzma库。
在深入分析libunwind之后,找到了问题的本质:libunwind会在有安装liblzma环境的情况下,编译minidebuginfo,而minidebuginfo依赖liblzma库(具体代码见:https://github.com/libunwind/libunwind/blob/v1.2-stable/configure.ac#L273)。同时libunwind也给出了是否启用minidebuginfo的选项–enable-minidebuginfo,因此我们关闭掉minidebuginfo即可。
最终通过设置libunwind的编译选项--enable-minidebuginfo=no
或--disable-minidebuginfo
,可优雅解决此问题:
./autogen.sh
# set disable-minidebuginfo to disable link liblzma
./configure --disable-shared --disable-minidebuginfo
make install
<完>
这篇关于解决依赖库libunwind编译报错undefined reference to ‘lzma_stream_buffer_decode‘的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!