一、分析
QT 打好的包,或生成的rpm文件,在安装或部署到干净的centos7 上启动时报错:
[root@localhost xxx]# ./XXX --no-sandbox
./XXX: error while loading shared libraries: libQt5WebEngineWidgets.so.5: cannot open shared object file: No such file or directory
[root@localhost xxx]#
[root@localhost xxx]# ./XXX --no-sandbox
./XXX: error while loading shared libraries: libQt5WebEngineWidgets.so.5: cannot open shared object file: No such file or directory
[root@localhost xxx]#
用ldd ./XXX 分析
[root@localhost public]# ldd ./XXX
./XXX: /lib64/libQt5Core.so.5: version `Qt_5.14' not found (required by ./XXX)
linux-vdso.so.1 => (0x00007ffed6176000)
libsqlite3.so.0 => /lib64/libsqlite3.so.0 (0x00007f787f779000)
libmysqlclient.so.21 => /usr/lib64/mysql/libmysqlclient.so.21 (0x00007f787f033000)
libQt5WebEngineWidgets.so.5 => not found
libQt5WebEngineCore.so.5 => not found
libQt5Quick.so.5 => not found
libQt5PrintSupport.so.5 => not found
libQt5Charts.so.5 => not found
libQt5Widgets.so.5 => not found
libQt5Gui.so.5 => not found
libQt5QmlModels.so.5 => not found
libQt5WebChannel.so.5 => not found
libQt5Qml.so.5 => not found
libQt5Network.so.5 => /lib64/libQt5Network.so.5 (0x00007f787faac000)
libQt5Positioning.so.5 => not found
libQt5Sql.so.5 => /lib64/libQt5Sql.so.5 (0x00007f787fa66000)
libQt5Core.so.5 => /lib64/libQt5Core.so.5 (0x00007f787eb86000)
libGL.so.1 => /lib64/libGL.so.1 (0x00007f787e8fa000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f787e6de000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f787e3d6000)
libm.so.6 => /lib64/libm.so.6 (0x00007f787e0d4000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f787debe000)
libc.so.6 => /lib64/libc.so.6 (0x00007f787daf0000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f787d8ec000)
libssl.so.10 => /lib64/libssl.so.10 (0x00007f787d67a000)
libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f787d217000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f787cffd000)
librt.so.1 => /lib64/librt.so.1 (0x00007f787cdf5000)
libz.so.1 => /lib64/libz.so.1 (0x00007f787cbdf000)
libsystemd.so.0 => /lib64/libsystemd.so.0 (0x00007f787c9ae000)
libicui18n.so.50 => /lib64/libicui18n.so.50 (0x00007f787c5af000)
libicuuc.so.50 => /lib64/libicuuc.so.50 (0x00007f787c236000)
libicudata.so.50 => /lib64/libicudata.so.50 (0x00007f787ac63000)
libpcre2-16.so.0 => /lib64/libpcre2-16.so.0 (0x00007f787a9f7000)
libgthread-2.0.so.0 => /lib64/libgthread-2.0.so.0 (0x00007f787a7f5000)
libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f787a4df000)
/lib64/ld-linux-x86-64.so.2 (0x00007f787fa2e000)
libGLX.so.0 => /lib64/libGLX.so.0 (0x00007f787a2ad000)
libX11.so.6 => /lib64/libX11.so.6 (0x00007f7879f6f000)
libXext.so.6 => /lib64/libXext.so.6 (0x00007f7879d5d000)
libGLdispatch.so.0 => /lib64/libGLdispatch.so.0 (0x00007f7879aa7000)
libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f787985a000)
libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f7879571000)
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f787936d000)
libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f787913a000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007f7878f35000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f7878d0e000)
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f7878ae8000)
liblz4.so.1 => /lib64/liblz4.so.1 (0x00007f78788d9000)
libgcrypt.so.11 => /lib64/libgcrypt.so.11 (0x00007f7878658000)
libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007f7878453000)
libdw.so.1 => /lib64/libdw.so.1 (0x00007f7878202000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f7877fa0000)
libxcb.so.1 => /lib64/libxcb.so.1 (0x00007f7877d78000)
libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f7877b68000)
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f7877964000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007f787775f000)
libelf.so.1 => /lib64/libelf.so.1 (0x00007f7877547000)
libbz2.so.1 => /lib64/libbz2.so.1 (0x00007f7877337000)
libXau.so.6 => /lib64/libXau.so.6 (0x00007f7877133000)
[root@localhost public]#
./XXX: /lib64/libQt5Core.so.5: version `Qt_5.14' not found (required by ./XXX)
libQt5WebEngineWidgets.so.5 => not found
libQt5WebEngineCore.so.5 => not found
libQt5Quick.so.5 => not found
libQt5PrintSupport.so.5 => not found
libQt5Charts.so.5 => not found
libQt5Widgets.so.5 => not found
libQt5Gui.so.5 => not found
libQt5QmlModels.so.5 => not found
libQt5WebChannel.so.5 => not found
libQt5Qml.so.5 => not found
上面这一堆 not found 都说明 在全局范围内找不到 这些包或库文件,但是你用名字一个个在安装文件的文件夹中搜索全部都有。
另外./XXX: /lib64/libQt5Core.so.5: version `Qt_5.14' not found (required by ./XXX)
可以看出ldd 是执行在全局默认路径下,寻址是默认到/lib64下面查找,大家会有一个冲动,是不是把上面 libQt5WebEngineWidgets.so.5 => not found libQt5WebEngineCore.so.5 => not found
libQt5Quick.so.5 => not found .... 一堆文件复制到lib64下面 会不报错,答案是肯定 的,但你不能那样做,因为这些文件还有自己的依赖,子子孙孙一大群,你必须全部放进去,过程中还有冲突,怎么办,一身汗?
回想,我们的目标是我们的XXX程序能运行即可,其它的能少放,就少放,真 不行的,我们做一个配置指向我们的程序安装路径即可
那么根据这个思路,我们下面将讲述 XXX.sh 、etc/ld.so.conf 等
二、处理过程
刚开始认为没有安装gcc 在yum 源上增加devtool-set8-gcc* 不过 发现依然报上面的错误,经过仔细思考,发现 如果你直接 运./XXX (XXX代码你的应用程序编译后的文件名) 总是报错,虽然你打包时,环境中,已经有了 plugins 、 lib、等文件夹,但是依然不行,
(注意此处批的plugins lib 是指QT打包时,copy的 系统 /opt/Qt5.14.1/Qt5.14.1/gcc_64/下面的lib, libexec,pluginx等,至于打包时为什么要copy系统的这个文件夹,请参考打包文档)
此时我们仔细参悟:就是我们的XXX程序在干净的 centos7 要想运行,必须构建公有或私有的QT环境,那么我们之前的XXX.sh 批处理命令的 用途就是这个,XXX.sh文件如下:
!/bin/sh
appname=`basename $0 | sed s,\.sh$,,`
dirname=`dirname $0`
tmp="${dirname#?}"
if [ "${dirname%$tmp}" != "/" ]; then
dirname=$PWD/$dirname
fi
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
$dirname/$appname "$@"
XXX.desktop
[Desktop Entry]
Name=XXX
Name[zh_CN]=XXX系统
Comment=XXX系统
Comment[zh_CN]=XXX系统
Exec=/usr/bin/xxx/XXX.sh --no-sandbox
Terminal=false
Type=Application
NoDisplay=false
不过增加这个后,还是需要将当前QT的部分指令指向 部署环境的路径:
这里我们的XXX 默认通地私有YUM 安装到/usr/bin/xxx下
生成rpm 包时,xxx.sepc中在部署后执行如下脚本:
shell_call_03_environment.sh 脚本如下:
#!/bin/bash
# Define log
TIMESTAMP=`date +%Y%m%d%H%M%S`
LOG=call_environment_${TIMESTAMP}.log
echo "Start execute nginx statement at `date`." >>${LOG}
#第一步:初始化程序Qt相对环境路径 解决问题: ./XXX: /lib64/libQt5Core.so.5: version `Qt_5.14' not found (required by ./MLESI)
echo "--第一步:配置XXX /etc/ld.so.conf QT静态库相对路径--开始--------------------------------------------------------------------------------------"
echo "--第一步:配置XXX /etc/ld.so.conf QT静态库相对路径--开始--------------------------------------------------------------------------------------">>${LOG}
#0.清空之前的记录,如有
sed -i "s/\/usr\/bin\/xxx\/plugins\/platforms/ /g" /etc/ld.so.conf
#第二步:配置XXX /etc/ld.so.conf QT静态库相对路径
echo "--第二步:配置XXX /etc/ld.so.conf QT静态库相对路径 --------------------------------------------------------------------------------------"
echo "--第二步:配置XXX /etc/ld.so.conf QT静态库相对路径--------------------------------------------------------------------------------------">>${LOG}
#include ld.so.conf.d/*.conf
#/usr/bin/xxx/lib
#//usr/bin/xxx/plugins/platforms
#echo "/usr/bin/xxx" >> /etc/ld.so.conf
echo "/usr/bin/xxx/plugins/platforms" >> /etc/ld.so.conf
#sudo ldconfig配置生效命令
#第三步:sudo ldconfig配置生效命令
echo "--第三步:sudo ldconfig配置生效命令--------------------------------------------------------------------------------------"
echo "--第三步:sudo ldconfig配置生效命令--------------------------------------------------------------------------------------">>${LOG}
sudo ldconfig
#第四步:chmod XXX.sh 授权命令
echo "--第四步:chmod 777 /usr/bin/xxx/XXX.sh配置授权命令--------------------------------------------------------------------------------------"
echo "--第四步:chmod 777 /usr/bin/xxx/XXX.sh配置授权命令--------------------------------------------------------------------------------------">>${LOG}
chmod 777 /usr/bin/xxx/XXX.sh
echo "初始化程序XXX Qt相对环境路径 -完成--------------------------------------------------------------------------------------"
echo "初始化程序XXX Qt相对环境路径-完成--------------------------------------------------------------------------------------">>${LOG}
echo -e "\n">>${LOG}
echo "below is output result.">>${LOG}
cat /tmp/temp.log>>${LOG}
echo "script executed successful.">>${LOG}
exit;
上需的shell_call_03_environment.sh 脚本执行完成后,实现了以下两个动作:
A. /etc/ld.so.conf 中的内容修改为如下:
include ld.so.conf.d/*.conf
/usr/bin/xxx/plugins/platforms
B.执行sudo ld config使其修改生效
[root@localhost etc]# sudo ldconfig
三、补充
为了保证 yum 或rpm 安装 XXX 程序后,菜单可以直接启动,快捷方式中XXX.desktop 中
必须启动XXX.sh 也不是 XXX
[Desktop Entry]
Name=XXX
Name[zh_CN]=XXX系统
Comment=XXX系统
Comment[zh_CN]=XXX系统
Exec=/usr/bin/xxx/XXX.sh --no-sandbox
Terminal=false
Type=Application
NoDisplay=false
如果:Exec=/usr/bin/xxx/XXX
仍然会报错,说加载静态库找不到文件,因为XXX本向没有设置相对环境变量的能力,只有通过.sh来设置,如果他能设置,大家也不会没事找麻烦,创建XXX.sh文件了,即然设置了XXX.sh就肯定有他存在理由和用途
四、总结
./XXX error while loading shared libraries: libQt5WebEngineWidgets.so.5: cannot open shared object file: No such file or directory
只要是找不到路径, No such file or directory cannot open shared object file 都是 相对路径不过,或者没有复制文件,如果文件肯定存在一定是 环境变量,全局变量中没有指向这个类库包所以的路径,那么就需要通过 .sh 命令,增加LD_LIBRARY_PATH 如:
LD_LIBRARY_PATH=$dirname
export LD_LIBRARY_PATH
$dirname/$appname "$@"
或者修改 ld.so.conf
或者修改 ~./profile 等