学习之旅:记录从pc ubuntu18.04移植qt项目到arm开发板(树莓派lite镜像)遇到的坑。
我不需要在树莓派上开发,所以树莓派上只需要qt即可。
前言
首先明确架构。架构对应不同的指令集,x86编译出来的可执行程序必然不能在arm运行。所以需要交叉编译。还有,不同位数的系统,所能运行的程序也不一样,说到底这个应该是运行库的问题。我一开始在64位的lite系统尝试运行,提示我找不到文件
-bash: ./test: cannot execute: required file not found
使用file命令查看文件详细属性
pi@raspberrypi:~ $ file ./project/test
./project/test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, with debug_info, not stripped
查看/usr/lib,缺少了linux-armhf.so.3文件,但肯定少了不止这个文件,干脆直接换成32位的lite,能跑起来再说,新的镜像内核版本为6,虽然可能有很多新特性,但我不太可能用到,加之我只是个小白,为了稳妥起见,特地找了旧版本的镜像(2023-05-03),自带的工具链也是8.3.0版本的,省的还得重新配置工具链。
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.10.103-v7l+ #1529 SMP Tue Mar 8 12:24:00 GMT 2022 armv7l GNU/Linux
配置交叉编译工具链
以下是野火的build-gcc.sh,安装的是8.3.0的arm-linux-gnueabihf工具链
#!/bin/sh
HOST=arm-linux-gnueabihf
SCRIPT_PATH=$(pwd)
#修改源码包解压后的名称
MAJOR_NAME=gcc-arm-linux-gnueabihf
#修改需要下载的源码版本前缀和后缀
OPENSRC_VER_PREFIX=8.3
OPENSRC_VER_SUFFIX=.0
PACKAGE_NAME=${MAJOR_NAME}-${OPENSRC_VER_PREFIX}${OPENSRC_VER_SUFFIX}
#定义压缩包名称
COMPRESS_PACKAGE=gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz
#定义编译后安装--生成的文件,文件夹位置路径
INSTALL_PATH=/opt/${PACKAGE_NAME}
#无需修改--下载地址
DOWNLOAD_LINK=https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/${COMPRESS_PACKAGE}
#下载源码包
do_download_src () {
echo "\033[1;33mstart download ${COMPRESS_PACKAGE}...\033[0m"
if [ ! -f "${COMPRESS_PACKAGE}" ];then
if [ ! -d "${PACKAGE_NAME}" ];then
wget -c ${DOWNLOAD_LINK}
fi
fi
echo "\033[1;33mdone...\033[0m"
}
#解压源码包
do_tar_package () {
echo "\033[1;33mstart unpacking the ${PACKAGE_NAME} package ...\033[0m"
mkdir -p ${INSTALL_PATH}
if [ ! -d "${PACKAGE_NAME}" ];then
tar -xf ${COMPRESS_PACKAGE} -C ${INSTALL_PATH} --strip-components=1
fi
echo "\033[1;33mdone...\033[0m"
}
#删除下载的文件
do_delete_file () {
cd ${SCRIPT_PATH}
if [ -f "${PACKAGE_NAME}" ];then
sudo rm -f ${PACKAGE_NAME}
fi
}
do_download_src
do_tar_package
# do_delete_file
exit $?
导出环境变量
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
export PATH=/opt/gcc-arm-linux-gnueabihf-8.3.0/bin:$PATH
qt的安装
pc端(开发)的安装使用
参考doc.embedfire.com/linux/imx6/base/zh/latest/linux_env/qt_cross_compiling.html#qt-creator
直接下载.run文件,http://download.qt.io/new_archive/qt,随便下一个就行,我之前选的是5.11.3版本,不是非换不可我都不换了。然后授予执行权限后执行
chmod +x ./xxxx.run
./xxxx.run
安装就不多说了,全是默认下一步。这样安装会将Qt CreatorIDE和Qt一起安装,不用自己配置环境😇
打开Qt CreatorIDE,随便打开自带的例程,不出意外
交叉编译qt
前面说了,在开发板上运行需要交叉编译。需要交叉编译的东西包括但不限于qt源码,qt工程代码。。。
(坑)
一开始我希望使用静态编译qt,因为静态编译出来的文件虽然比较大,但是不用配置动态库,不需要关心环境。我选择交叉编译5.13.0版本的qt,主要是因为怎么都无法静态编译5.11.3版本的qt,换成5.13.0一下就通过了。然后ide配置好,编译工程,放到开发板
提示缺少ts的相关库,这个是触摸屏的相关库,直接从pc交叉编译好的tslib库文件复制到开发板的/usr/lib即可,哪怕程序是静态编译的,但是运行时仍然可能需要某些共享库,这些库往往是第三方的,编译静态qt并不会编译进去
pi@raspberrypi:~/project $ readelf -d ./analogclock
Dynamic section at offset 0x4ed0 contains 33 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libts.so.0]
0x00000001 (NEEDED) Shared library: [libQt5Gui.so.5]
0x00000001 (NEEDED) Shared library: [libQt5Core.so.5]
0x00000001 (NEEDED) Shared library: [libpthread.so.0]
0x00000001 (NEEDED) Shared library: [libstdc++.so.6]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.6]
放好之后还是不行,果然没那么容易,插件找不到。
pi@raspberrypi:~/project $ ./analogclock
qt.qpa.plugin: Could not find the Qt platform plugin "linuxfb"
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
解决方法大概是要么静态编译插件(不确定,已尝试将libqlinuxfb.a移至开发板,导出目录,错误依旧,有大佬吗😭),要么动态编译qt,这样的话pc上,开发板上都需要有qt
动态编译qt
解压、进入目录
然后配置、编译、安装三部曲
./configure -prefix /opt/qt-everywhere-src-5.13.0 -xplatform linux-arm-gnueabi-g++ -release -opensource -confirm-license -no-openssl -no-opengl -no-xcb -no-eglfs -no-compile-examples -no-pkg-config -no-iconv -no-glib -no-tslib -no-alsa
我没有尝试将不带tslib的qt放进开发板,所以我不确定这样在开发板程序能不能运行,建议还是把tslib和其他你需要的功能编译都进去
make && make install
ide配置套件kits
不多说了,感觉篇幅好长,步骤基本就是1.配置交叉编译工具链,2.配置刚才交叉编译的qt,3.配置kits。这里有详细的教程
将交叉编译的qt源码移至开发板
qt位置我放到了/opt/qt-everywhere-src-5.13.0
导出环境变量
export QTDIR=/opt/qt-everywhere-src-5.13.0
export QT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins/
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export QT_QPA_FONTDIR=/usr/lib/fonts
export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0
交叉编译工程
选择你的kits,然后点击锤子
将编译出来的二进制可执行文件放到开发板,给权限,执行
文章可能有不妥的地方,我也刚开始学习linux,如不正确,请指出