在Ubuntu平台上使用qmake交叉编译生成的Qt应用(example)部署到树莓派Bookworm 64位系统时,获取并确保正确链接依赖库是关键环节。通过交叉编译工具链的sysroot目录识别依赖库,再通过Ubuntu的多架构支持安装ARM64版本依赖包,最后将应用和依赖库一起打包部署到树莓派,可以确保应用顺利运行。这一过程需要理解交叉编译环境的工作原理,特别是工具链的sysroot目录如何模拟目标系统环境,以及如何正确识别和收集应用所需的依赖库。
一、识别应用依赖库的方法
在Ubuntu主机上,使用交叉工具链的ldd命令结合sysroot参数是最有效识别example应用依赖库的方法。交叉编译生成的二进制文件无法在x86架构的Ubuntu主机上直接运行,因此需要借助交叉工具链的专用工具来分析其依赖关系。具体命令如下:
aarch64-linux-gnu-ldd --sysroot=/usr/aarch64-linux-gnu/sysroot example
该命令会输出example应用所依赖的所有动态链接库(.so文件)及其路径。如果路径显示为”not found”,则表明该库未包含在交叉工具链的sysroot目录中,需要额外安装 [1] 。交叉工具链的sysroot目录模拟了树莓派Bookworm 64位系统的文件系统结构,通常位于/usr/aarch64-linux-gnu/sysroot或交叉工具链安装路径下的类似位置 [17] 。
如果交叉工具链未正确配置或ldd命令不可用,可以使用以下替代方法识别依赖库:
objdump -p example | grep NEEDED
或
readelf -d example | grep NEEDED
这些命令会直接列出example应用所需的共享库名称,但不会显示具体路径。获取到库名称后,需进一步确认这些库是否存在于交叉工具链的sysroot目录中 。
二、Ubuntu主机上安装ARM64依赖库
要获取example应用所需的依赖库,首先需要在Ubuntu主机上配置ARM64架构支持:
sudo dpkg --add-architecture arm64
sudo apt update
然后,需要添加树莓派Bookworm 64位系统的软件源。编辑/etc/apt/sources.list.d/raspi.list文件:
sudo nano /etc/apt/sources.list.d/raspi.list
添加以下内容(使用清华大学镜像加速下载):
deb https://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ bookworm main non-free contrib rpi
deb [arch=arm64] https://mirrors.tuna.tsinghua.edu.cn/raspbian/multiarch/ bookworm main
保存并退出后更新软件包列表:
sudo apt update
现在,可以通过apt命令安装example应用所需的ARM64版本依赖库。例如,如果example应用依赖libqt5widgets5,则安装命令为:
sudo apt install libqt5widgets5:arm64
注意依赖包名的格式,ARM64架构的包名通常以”:arm64”结尾 [26] 。安装完成后,这些库文件会自动放置在Ubuntu主机的ARM64架构库目录中,通常是/usr/aarch64-linux-gnu/sysroot/usr/lib/aarch64-linux-gnu/ 。
对于Qt应用,常见的依赖库包括:
- libqt5core5a:arm64
- libqt5Widgets5:arm64
- libqt5Network5:arm64
- libstdc++6:arm64
- libgcc-s1:arm64
如果某些库无法通过apt安装,可能需要手动编译并安装到交叉工具链的sysroot目录中 [17] 。例如,安装OpenSSL的ARM64版本:
tar zxvf openssl-3.0.8.tar.gz
cd openssl-3.0.8/
./config linux-aarch64 no-asm shared no-async --prefix=/opt/aarch64 --cross-compile-prefix=aarch64-linux-gnu-
make -j4
sudo make install
安装完成后,需要确保这些库文件被正确放置在交叉工具链的sysroot目录中,以便在交叉编译时能够被正确链接 [17] 。
三、依赖库的收集与验证
获取所有依赖库后,需要将它们收集到一个目录中,以便与example应用一起部署到树莓派上。可以使用以下命令自动收集依赖库:
mkdir -p deployment/lib
aarch64-linux-gnu-ldd --sysroot=/usr/aarch64-linux-gnu/sysroot example | grep '=> /' | awk '{print $3}' | xargs -I{} cp -d {} deployment/lib/
这个命令会在deployment目录下创建一个lib子目录,并将example应用依赖的所有库文件复制到该目录中。使用-cp -d参数可以保留符号链接,避免复制冗余文件 [17] 。
收集完成后,需要验证这些库文件的架构是否正确:
file deployment/lib/libQt5Widgets.so.5 | grep 'aarch64'
如果输出显示”ARM aarch64”,则表示该库文件是为ARM64架构编译的,可以正常在树莓派上运行。如果显示其他架构或”not found”,则需要重新安装或获取正确的ARM64版本库文件。
对于复杂的Qt应用,可能会依赖一些非Qt的系统库,如OpenGL、X11等 [25] 。这些库通常需要在树莓派上安装对应的软件包,或通过交叉工具链的sysroot目录提供。如果在sysroot目录中找不到这些库,可能需要在树莓派上安装相应的软件包,或在Ubuntu主机上安装ARM64版本的依赖包。
四、应用与依赖库的打包部署
收集并验证所有依赖库后,可以将example应用和依赖库一起打包部署到树莓派上:
tar -czvf appDeployment.tar.gz deployment/
使用scp命令将打包好的应用传输到树莓派:
scp appDeployment.tar.gz pi@树莓派IP:/home/pi/
在树莓派上解压并设置运行环境:
tar -xzvf appDeployment.tar.gz
cd deployment
export LD_LIBRARY_PATH=$PWD/lib:$LD_LIBRARY_PATH
./example
设置LD_LIBRARY_PATH环境变量是为了让系统在运行example应用时能够找到部署在lib目录中的依赖库 [5] 。如果希望应用能够直接运行,可以将依赖库复制到树莓派的系统库目录中:
sudo cp -r deployment/lib/* /usr/lib/aarch64-linux-gnu/
但这种方法可能会与系统已安装的库文件冲突,特别是在版本不一致的情况下。因此,更推荐使用相对路径部署依赖库,避免影响树莓派系统的其他应用。
如果example应用依赖的某些库在树莓派上不存在,需要在树莓派上安装对应的软件包:
sudo apt update
sudo apt install <包名>
例如,如果应用依赖libqt5 opengl5,则安装命令为:
sudo apt install libqt5opengl5
确保树莓派上的软件包版本与Ubuntu主机上交叉编译使用的库版本兼容,避免因版本不匹配导致运行时错误。
五、交叉编译环境的配置与优化
为确保交叉编译生成的应用能够正确识别依赖库,需要在Ubuntu主机上正确配置交叉编译环境。首先,安装交叉编译工具链:
sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
然后,配置qmake的交叉编译参数。在项目.pro文件中添加:
target.path = /home/pi/deployment
INSTALLS += target
# 交叉编译配置
contains(QT_ARCH,linux-aarch64) {
message("Configuring for AArch64 cross compiles")
QMAKE_CXX = aarch64-linux-gnu-g++
QMAKE_CC = aarch64-linux-gnu-gcc
QMAKE_AR = aarch64-linux-gnu-ar
QMAKE_RANLIB = aarch64-linux-gnu-ranlib
QMAKE_OBJDUMP= aarch64-linux-gnu-objdump
# 指定sysroot路径
QMAKE_CXXFLAGS += -I/usr/aarch64-linux-gnu/sysroot/usr/include
QMAKE_LFLAGS += -L/usr/aarch64-linux-gnu/sysroot/usr/lib/aarch64-linux-gnu
# 指定目标平台
QMAKE_CXXFLAGS += -march=armv8-a
QMAKE_CFLAGS += -march=armv8-a
}
这些配置确保了qmake在编译时使用正确的交叉编译工具和库路径 [3] 。此外,还可以在Ubuntu主机上设置环境变量,简化交叉编译过程:
export SYSROOT=/path/to/your-sysroot
export PATH=$PATH:/usr/aarch64-linux-gnu/bin
export ARCH=aarch64
export CROSS_COMPILE=aarch64-linux-gnu-
这些环境变量可以在.bashrc文件中设置,以便每次登录时自动加载:
echo 'export PATH=$PATH:/usr/aarch64-linux-gnu/bin' >> ~/.bashrc
echo 'export ARCH=aarch64' >> ~/.bashrc
echo 'export CROSS_COMPILE=aarch64-linux-gnu-' >> ~/.bashrc
source ~/.bashrc
优化交叉编译环境可以提高编译效率和准确性,减少依赖库遗漏的可能性 。此外,还可以考虑使用工具链管理工具,如update-alternatives,来管理多个版本的交叉编译工具链:
sudo update-alternatives --install /usr/bin/aarch64-linux-gnu-gcc aarch64-linux-gnu-gcc /usr/bin/aarch64-linux-gnu-gcc-10 20
sudo update-alternatives --config aarch64-linux-gnu-gcc
这允许在需要时快速切换不同版本的交叉编译工具链,适应不同项目的编译需求 。
六、常见问题及解决方案
在交叉编译和部署过程中,可能会遇到以下常见问题:
- 依赖库未找到:在交叉编译时,如果qmake报错找不到某些库,需要在Ubuntu主机上安装对应的ARM64版本依赖包,或在交叉工具链的sysroot目录中提供这些库。
- 库版本不匹配:如果应用在树莓派上运行时报错”version `GLIBC_2.34’ not found”,通常是因为Ubuntu主机上的库版本与树莓派上的库版本不一致。解决方法是确保交叉工具链的sysroot目录中的库版本与树莓派系统一致,或在树莓派上安装相同版本的库。
- 符号链接问题:某些库文件是符号链接,直接复制可能导致路径错误。可以使用以下命令收集依赖库并保留符号链接:
aarch64-linux-gnu-ldd --sysroot=/usr/aarch64-linux-gnu/sysroot example | grep '=> /' | awk '{print $3}' | xargs -I{} cp -d {} deployment/lib/
- 架构不兼容:如果应用在树莓派上无法运行并报错”cannot execute binary file”,可以使用file命令检查应用的架构:
file example
正确的输出应为”ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV)“ [14] 。如果不是,需要重新配置交叉编译环境,确保使用正确的工具链和参数进行编译。
- 链接错误:在交叉编译时,如果出现”undefined reference to”错误,通常是因为缺少某些库或头文件。解决方法是在Ubuntu主机上安装对应的ARM64版本依赖包,或在交叉工具链的sysroot目录中提供这些文件。
七、自动化部署脚本
为了简化部署过程,可以编写一个自动化脚本,自动识别、收集依赖库并打包部署:
#!/bin/bash
APP_NAME="example"
DEPLOY_DIR="deployment"
LIB_DIR="$DEPLOY_DIR/lib"
# 创建部署目录
mkdir -p $LIB_DIR
# 收集依赖库
aarch64-linux-gnu-ldd --sysroot=/usr/aarch64-linux-gnu/sysroot $APP_NAME | grep '=> /' | awk '{print $3}' | xargs -I{} cp -d {} $LIB_DIR/
# 验证依赖库架构
for lib in $LIB_DIR/*; do
if ! file $lib | grep -q 'ARM aarch64'; then
echo "错误:$lib不是ARM aarch64架构"
exit 1
fi
done
# 复制应用
cp $APP_NAME $DEPLOY_DIR/
# 打包应用
tar -czvf $APP_NAME-deployment.tar.gz $DEPLOY_DIR/
# 清理临时文件
rm -rf $DEPLOY_DIR/
这个脚本会自动执行以下操作:
- 创建部署目录和依赖库目录
- 使用交叉工具链的ldd命令收集example应用的依赖库
- 验证所有依赖库的架构是否正确
- 复制example应用到部署目录
- 打包应用和依赖库
- 清理临时文件
使用自动化脚本可以减少人为错误,确保每次部署都包含所有必要的依赖库 [17] 。此外,还可以将部署过程集成到CI/CD管道中,实现自动化部署。
八、最佳实践与建议
在交叉编译和部署Qt应用到树莓派Bookworm 64位系统时,建议遵循以下最佳实践:
- 使用标准的交叉编译工具链:从Ubuntu仓库安装标准的交叉编译工具链(如gcc-aarch64-linux-gnu),避免使用非官方或未经验证的工具链。
- 明确指定sysroot路径:在交叉编译配置中明确指定sysroot路径,确保链接器能够找到正确的依赖库。
- 使用多架构支持:在Ubuntu主机上启用ARM64架构支持,以便能够安装和管理ARM64版本的依赖包。
- 验证库文件架构:在部署前验证所有依赖库的架构是否正确,避免部署到树莓派后出现架构不兼容的问题。
- 使用相对路径部署依赖库:将依赖库部署在应用的相对路径中,避免影响树莓派系统的其他应用。
- 定期更新交叉工具链和依赖库:随着树莓派系统和Qt框架的更新,交叉工具链和依赖库也需要定期更新,以确保兼容性和安全性。
通过遵循这些最佳实践,可以确保Qt应用在树莓派Bookworm 64位系统上的顺利部署和运行。此外,还可以考虑使用Docker容器来模拟树莓派Bookworm 64位系统环境,进行应用的测试和部署,减少环境差异带来的问题。
最后,如果应用非常复杂或依赖的库非常特殊,可能需要考虑在树莓派上直接编译和安装应用,而不是在Ubuntu主机上交叉编译。这可以通过在树莓派上安装Qt开发环境和必要的编译工具来实现 。
总之,获取example应用的依赖库并成功部署到树莓派Bookworm 64位系统,需要理解交叉编译环境的工作原理,正确识别和收集依赖库,并确保它们与目标系统的兼容性。通过合理配置Ubuntu主机的交叉编译环境,添加正确的软件源,安装必要的依赖包,并使用自动化脚本简化部署过程,可以高效地实现Qt应用在树莓派上的顺利运行。
参考来源:
1. CMake指定交叉编译指南:从编译器设置到验证(CMake Cross-…
4. ubuntu 18.0交叉编译Qt5.12.12生成库文件_could not findqmakespec ‘aarch64-linux-gnu-g+’.-优快云博客
5. 如何在交叉编译的环境中,使用x86的qmake,使用arm的libQt5OpenGL.so.5.15.3-优快云文库
7. 树莓派Liunx相关_bookworm安装qt5-优快云博客
8. 树莓派+QT5.9.9交叉编译,100%可以使用的交叉编译-Hiker天下-博客园
10. Android-NDK-clang 编译 FFmpeg-知乎
16. 6、在windows系统里面安装Eclipse IDE和交叉编译器,编译生成…
18. Ubuntu交叉编译aarch64的opencv+ffmpeg
20. raspbian|镜像站使用帮助|清华大学开源软件镜像站|Tsinghua Open Source Mirror
22. 一键编译QT5源码脚本(交叉编译arm64、mips64版本)麒麟arm64 qt开发依赖库-优快云博客
23. MPLAPACK version 2.0.1 user manual
24. 小白级手把手教树莓派3B系统镜像部署:Raspberry Pi OSBookworm(包含配置静态IP+配置镜像源)努力赚钱的小智-博客园
25. Aarch64(arm64)下编译QT5.15.5(xcb、webengine)QTCreator4.13.3_qt_回忆丿从前-华为开发者空间
26. 树莓派3B+刷了Pi OS 12(Debian12bookworm)后软件源更换清华(备忘)bookworm换源-优快云博客
27. QT5交叉编译保姆级教程(arm64、mips64)skyyx2002-GitCode 开源社区
30. ubuntu上安装arm64的向日葵_ubuntu_科学的发展-只不过是读大自然写的代码-2048 AI社区
31. raspbian|镜像站使用帮助|清华大学开源软件镜像站|Tsinghua Open Source Mirror
32. 搭建ubuntu arm64环境_debootstraparm64-优快云博客
34. 树莓派5/树莓派最新系统(64位bookworm)安装ROS_树莓派5 ros-优快云博客
35. 如何搜索一个包是否在你的 Linux 发行版中-知乎
36. 树莓派4基于Debian GNU/Linux 12(Bookworm)系统安装-优快云博客
38. 树莓派5bookworm64(32)位系统安装opencv问题_树莓派5安装opencv4-优快云博客
43. 树莓派」上海晶珩」EDATEC」在 Raspberry Pi 64 位 OS 上安装 …
44. Linux交叉编译(toolchain)ARMaarch64版 libnl.so 库-悟透-博客园
45. 树莓派5/树莓派最新系统(64位bookworm)安装ROS_树莓派5 ros-优快云博客
46. 深入解析aarch64-linux交叉编译器的使用与配置-优快云博客
48. 树莓派Liunx相关_bookworm安装qt5-优快云博客
49. Ubuntu20.04配置aarch64的Qt6环境(亲测有效)ubuntuaarch64-优快云博客
51. 构建树莓派交叉编译环境(基于虚拟机ubuntu18)哔哩哔哩
53. ubunut搭建aarch64cuda交叉编译环境记录_aarch64-linux-gnu ubuntu-优快云博客
55. 树莓派」上海晶珩」EDATEC」在 Raspberry Pi 64 位 OS 上安装 …
56. raspbian|镜像站使用帮助|清华大学开源软件镜像站|Tsinghua Open Source Mirror
57. 例如我需要下载达梦数据库安装包,查看的linux是aarch64,达梦官网给出的支持cpu平台有x86,飞腾2000,龙芯3000,海光,鲲鹏920,龙芯5000…
60. 树莓派」上海晶珩」EDATEC」在 Raspberry Pi 64 位 OS 上安装 …
61. 例如我需要下载达梦数据库安装包,查看的linux是aarch64,达梦官网给出的支持cpu平台有x86,飞腾2000,龙芯3000,海光,鲲鹏920,龙芯5000…

3231

被折叠的 条评论
为什么被折叠?



