undefined symbol: _ZdlPvm, version Qt_5错误以及error while loading shared libraries: xxx.so解析

文章讲述了在Ubuntu系统中遇到的Qt项目编译错误,主要问题是由于Qt版本不匹配和库文件路径设置不当。作者提供了检查和解决符号查找错误、版本问题以及设置LD_LIBRARY_PATH的详细步骤。
摘要由CSDN通过智能技术生成

今天在ubuntu系统编译一个qt项目的时候,遇到了如下报错:

/home/aruchid/Qt5.12.1/5.12.1/gcc_64/bin/uic: symbol lookup error: /home/aruchid/Qt5.12.1/5.12.1/gcc_64/bin/uic: undefined symbol: _ZdlPvm, version Qt_5

make[2]: *** [cloudtool/CMakeFiles/cloudtool_autogen.dir/build.make:71:cloudtool/CMakeFiles/cloudtool_autogen] 错误 1

make[1]: *** [CMakeFiles/Makefile2:271:cloudtool/CMakeFiles/cloudtool_autogen.dir/all] 错误 2

make: *** [Makefile:136:all] 错误 2

经过初步的分析,发现可能有几个原因

  1. 符号查找错误:这表明uic工具尝试访问一个它找不到的符号(_ZdlPvm),这通常是因为库文件不匹配或者缺失某些必要的库。_ZdlPvm是C++的删除操作符delete的mangled(混淆后的)名称,涉及特定版本的Qt库。

  2. 版本问题:错误中提到了version Qt_5,这可能表明你的环境中安装的Qt库版本和uic工具期望的版本不匹配。这可以由多个版本的Qt库存在或环境变量设置不正确导致。依赖库未找到

后面经过分析,我确定是Qt安装的版本和系统使用的QT版本不一致,程序运行默认先从系统的 /usr/lib/x86_64-linux-gnu/目录查找动态库,编译的使用了Qt5.12.1,而系统目录是其他的版本,所以会出现未定义的错误;不能替换系统目录下的Qt库,否则系统会崩溃。

可能的解决办法:

  • 使用 ldd -r , 确定系统库中是否存在所依赖的库
  • 执行 ldconfig 命令更新 ld 缓存
  • 执行 ldconfig -p | grep {SO_NAME} 查看是否能找到对应的库
  • 检查 LD_LIBRATY_PATH 是否设置了有效的路径

在CMake中指定程序运行时引用特定的动态库(如Qt库)通常涉及到几个方面的设置,包括编译时的链接和运行时的环境配置。在CMakeLists.txt文件中,你可以控制编译时链接到的Qt库,但运行时库的路径主要是通过环境变量或操作系统的配置来管理的。

为了简化开发和测试,可以通过设置LD_LIBRARY_PATH(Linux/Mac)或PATH(Windows)环境变量来指示操作系统在运行时查找库的位置。这可以在用户的shell配置文件中设置,或在应用程序的启动脚本中设置:

export LD_LIBRARY_PATH="/path/to/Qt5.12.1/5.12.1/gcc_64/lib:$LD_LIBRARY_PATH"

通过上述方法,你可以确保你的应用程序在编译时和运行时都使用指定版本的Qt库。这对于避免版本冲突和运行时错误非常重要,特别是在依赖特定库功能或避免系统库冲突时。


其实简单来说就是,通过设置环境变量来指定程序运行查找的库。

然后又遇到了如下的问题: ./cloudtool: error while loading shared libraries: libQt5X11Extras.so.5: cannot open shared object file: No such file or directory

这个错误表明你的应用程序在尝试运行时未能找到libQt5X11Extras.so.5这个共享库文件。这通常是因为库文件不在系统期望的库路径中,或者相关的环境变量没有正确设置。以下是解决这个问题的步骤:

首先,确保你的系统中安装了Qt5X11Extras模块,并找到libQt5X11Extras.so.5文件的位置。通常这个库文件位于Qt安装目录下的lib文件夹内。你可以使用find命令来帮助查找:

find /home/aruchid/Qt5.12.1/5.12.1/gcc_64/ -name libQt5X11Extras.so.5

找到库文件后,你需要确保这个库文件的路径被添加到LD_LIBRARY_PATH环境变量中。这样操作系统在运行时就可以找到它:

export LD_LIBRARY_PATH=/path/to/Qt5.12.1/5.12.1/gcc_64/lib:$LD_LIBRARY_PATH

确保替换路径为实际的路径,其中包含libQt5X11Extras.so.5

或者也可以使设置永久生效

如果你不想每次打开新终端时都重新输入这条命令,可以将其添加到你的用户配置文件中,例如~/.bashrc~/.bash_profile(取决于你的shell和操作系统):

echo 'export LD_LIBRARY_PATH=/home/aruchid/Qt5.12.1/5.12.1/gcc_64/lib:$LD_LIBRARY_PATH' >> ~/.bashrc source ~/.bashrc

这将确保每次你打开一个新的终端窗口时,LD_LIBRARY_PATH都已正确设置。

另一个解决方案是设置可执行文件的RPATH,这样它会在特定的目录下搜索库,而无需设置环境变量。这可以通过修改CMakeLists.txt来实现,如下所示:

set(CMAKE_INSTALL_RPATH "/home/aruchid/Qt5.12.1/5.12.1/gcc_64/lib") set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)

命令总结

ldd 命令,用于查找某个动态库所依赖的库是否存在,是 Linux 系统中用于查看可执行文件或动态链接库(共享库)依赖的动态链接库(库文件)的工具。它显示了一个程序在运行时将会加载哪些库,以及这些库的位置。

ldd example

linux-vdso.so.1 (0x00007ffce8dab000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1e8b1d1000)
	         /lib64/ld-linux-x86-64.so.2 (0x00007f1e8b5c1000)

这里,每行都表示一个库依赖:

  • 第一列显示库的名称。
  • 第二列使用箭头 => 显示库文件的路径(如果找到的话)。
  • 第三列显示库文件加载到内存中的地址(可选信息,视系统而定)。

注意事项

  • 如果某个库没有找到,ldd 通常会在相应的行显示 not found
  • 使用 ldd 命令时需要谨慎,因为这个命令实际上会加载指定的库,如果库中有恶意代码,可能会造成安全风险。对不信任的二进制文件使用 ldd 时应特别小心。

nm 命令,用于读取库被导出的符号

$ nm -gDC libSXVideoEngineJni.so | grep -i license
0000000000008110 T __ZN13SXVideoEngine6Public7License10SetLicenseEPKc
0000000000008130 T __ZN13SXVideoEngine6Public7License13LicenseStatusEv
0000000000008190 T __ZN13SXVideoEngine6Public7License19IsVideoCutSupportedEv
0000000000008170 T __ZN13SXVideoEngine6Public7License26IsDynamicTemplateSupportedEv
0000000000008150 T __ZN13SXVideoEngine6Public7License26IsStadardTemplateSupportedEv

readelf 用于读取 elf 文件的相关信息

$ readelf -d libSXVideoEngineJni.so | grep rpath
 0x000000000000000f (RPATH)              Library rpath:
 [/home/slayer/workspace/SXVideoEngine-Core/Render/cmake-build-
 debug:/home/slayer/workspace/SXVideoEngine-Core/Render/../../SXVideoEngine-Core-Lib/blend2d/linux/lib]

c++filt 用于获取符号的原始名

$ c++filt __ZN13SXVideoEngine6Public7License10SetLicenseEPKc
SXVideoEngine::Public::License::SetLicense(char const*)

  • 31
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值