想要在嵌入式设备中运行qt程序(其他的程序一样),要在嵌入式设备中将程序运行所依赖的库部署。网上部署方式千万种,例如直接将库编译之后写入镜像,然后用这个镜像来安装树莓派的系统;也有在嵌入式设备中直接安装qt。本文介绍最普遍的部署方式,就是在pc端的ubuntu中交叉编译库源码,然后上传编译好的库到树莓派,最后配置qt creator交叉编译的kit来实现在pc端编译自码程序,上传到树莓派运行。
树莓派版本:Raspberry Pi 3 Model B
树莓派系统:Raspbian(stretch)
PC端系统:ubuntu 18.04
Qt库版本:5.12.5
关于你的系统是stretch还是buster,可以查看系统镜像源的方式来确定
cat /etc/apt/sources.list
Qt源代码下载(5.12.5):
http://download.qt.io/archive/qt/5.12/5.12.5/single/
ubuntu下Qt安装包(.run、5.12.5):
http://download.qt.io/archive/qt/5.12/5.12.5/
下载交叉编译连
(gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf):
https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/
下载cross-compile-tools:
git clone https://github.com/darius-kim/cross-compile-tools.git
使用迅雷下载可破下载速度慢的问题
下文中将分别在树莓派端和电脑端进行配置
[PI]代表树莓派端
[PC]代表电脑端
我建议是创建一个文件夹,专门放置这些交叉编译文件以及一切跟qt交叉编译环境以及编译好的库文件和文件夹。我是创建了一个名为raspi文件夹
[PI]更新软件源并下载必要软件
更新固件并重启
sudo rpi-update
reboot
先把系统默认的源进行备份
sudo cp /etc/apt/sources.list /etc/apt/sources.list.pre
sudo cp /etc/apt/sources.list.d/raspi.list /etc/apt/sources.list.d/raspi.list.pre
我们的系统是stretch版本,这一点要注意。接下来把镜像源设置成国内的,这样下载速度快一些。
编辑/etc/apt/sources.list删除原有内容,并添加以下内容
deb http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ stretch main contrib non-free rpi
#deb-src http://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ stretch main contrib non-free rpi
编辑/etc/apt/sources.list.d/raspi.list删除原有内容,并添加以下内容
deb http://mirror.tuna.tsinghua.edu.cn/raspberrypi/ stretch main ui
#deb-src http://mirror.tuna.tsinghua.edu.cn/raspberrypi/ stretch main ui
更新
sudo apt update
sudo apt-get upgrade
有教程说需要安装以下两个包,但是我没有成功安装但是最后也可以使用。我列出来有需要的人可以试一试
sudo apt-get build-dep qt4-x11
sudo apt-get build-dep libqt5gui5
以下软件要成功安装
sudo apt-get install libudev-dev libinput-dev libts-dev libxcb-xinerama0-dev libxcb-xinerama0
sudo apt-get install libfontconfig1-dev libdbus-1-dev libfreetype6-dev libicu-dev libinput-dev libxkbcommon-dev libsqlite3-dev libssl-dev libpng-dev libjpeg-dev libglib2.0-dev libraspberrypi-dev libpq-dev libmariadbclient-dev bluez libbluetooth-dev build-essential
[PI]准备目标文件夹
在树莓派的/usr/local下创建qt5pi文件夹,之后的的库文件会放在这个文件夹之下
sudo mkdir /usr/local/qt5pi
sudo chown pi:pi /usr/local/qt5pi
[PI]配置调试运行环境
首先需要给/opt文件夹权限,因为如果是要配置远程调试的话,编译好的可执行文件会放在这个文件夹下
sudo chmod -R 777 /opt
远程调试需要安装其他软件
sudo apt-get install gdbserver
[PC]配置交叉编译环境
解压交叉编译工具到raspi/cross-compile-tools
cd ~/raspi/cross-compile-tools
tar xvJf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
配置交叉编译链的环境变量
cd ~
gedit .bashrc
PATH=$PATH:~/raspi/cross-compile-tools/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin
保存退出后,刷新变量文件
source .bashrc
检查交叉编译环境安装是否正确
arm-linux-gnueabihf-g++ -v
输出以下内容则配置正确
[PC]创建sysroot
sysroot是树莓派上的文件在PC上的拷贝,编译过程中需要的头文件、库等会在这里查找,sysroot文件夹创建在raspi文件夹下,并在sysroot下创建usr和opt文件夹
cd ~/raspi
mkdir sysroot
mkdir sysroot/usr
mkdir sysroot/opt
使用rsync同步树莓派文件夹到pc端,raspberrypi_ip代表树莓派的IP地址
rsync -avz pi@raspberrypi_ip:/lib sysroot
rsync -avz pi@raspberrypi_ip:/usr/include sysroot/usr
rsync -avz pi@raspberrypi_ip:/usr/lib sysroot/usr
rsync -avz pi@raspberrypi_ip:/opt/vc sysroot/opt
下一步将sysroot的符号调整为相对的
cd ~/raspi
wget https://raw.githubusercontent.com/riscv/riscv-poky/master/scripts/sysroot-relativelinks.py
chmod +x sysroot-relativelinks.py
./sysroot-relativelinks.py sysroot
[PC]配置Qt
将之前下载好的Qt源码解压到raspi
cd ~/raspi
tar xvf qt-everywhere-src-5.12.5.tar
可以给源码文件夹换成一个自己喜欢的名字,我把文件夹命名为raspi-qt-5125
mv qt-everywhere-src-5.12.5 raspi-qt-5125
然后我们使用configure来配置编译Qt所需要的一些模块,configure可选择的参数很多,大家可以参考下面这个文章写的不错:https://blog.csdn.net/xi_gua_gua/article/details/53413930
我们列举出一些参数来配置,首先来编译qtbase
cd ~/raspi/raspi-qt-5125/qtbase
./configure -release -no-opengl -device linux-rasp-pi3-vc4-g++ -device-option CROSS_COMPILE=/home/lmhubuntu/raspi/cross-compile-tools/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- -sysroot ~/raspi/sysroot -opensource -confirm-license -make libs -prefix /usr/local/qt5pi -extprefix ~/raspi/qt5pi -hostprefix ~/raspi/qt5pi-host -v
接下来对里面的参数做一些解释
-release
加上此选项编译程序Qt不会做出优化,往往在开发过程使用此选项,是默认选项
-opengl es2
表示编译带opengl es2的Qt,如果编译出错执行,则执行sudo apt-get install libgles2-mesa-dev
-device linux-rasp-pi3-vc4-g++
选择的目标设备,目标设备的配置文件可在/qtbase/mkspec/device找到
-device-option CROSS_COMPILE=
~/raspi/cross-compile-tool/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
交叉编译器的路径
-sysroot ~/raspi/sysroot
刚刚构建的树莓派文件系统的路径
-opensource
以开源版本发布程序
-confirm-license
自动确认许可证(使用开源或是商业)
-make libs
在make时添加要构建的组件. (默认为:libs tools examples)
-prefix /usr/local/qt5pi
目标板的Qt程序安装目录,默认路径是/usr/local/Qt-版本号 (make完成后看看PC端对应目录下是否有qt5pi目录)
-extprefix ~/raspi/qt5pi
指定Qt 交叉编译库存放位置。默认路径是SYSROOT/PREFIX。此目录最后需要同步rsysc到目标板的/usr/local/目录下。
-hostprefix ~/raspi/qt5-host
指定Qt 编译的可执行工具存放的位置,比如qmake,默认路径与-extprefix参数一致。
-no-use-gold-linker
不要使用GNU gold linker进行链接。对于 5.9.1 或更高版本的 Qt必须添加此选项,不然编译会报错
-v
显示每个步骤的详细信息
-no-gbm
不要编译 GBM 的后端
[PC]编译并安装Qt库
接下来对Qt库进行编译并安装,这个过程应该是几十分钟,具体取决于电脑的速度。这个安装是安装在~/raspi/qt5pi下
cd ~/raspi/raspi-qt-5125/qtbase
make -j4
make install
编译完成之后,同步到树莓派下的/usr/local/qt5pi下
cd ~/raspi
rsync -avz qt5pi pi@raspberrypi_ip:/usr/local
[PC]编译其他模块
我们之前之所没有一次性全部编译所有模块,首先是因为不是所有模块我们都用得到,其次是因为其中会出很多错,所以就每个模块单独编译。
之前已经创建出qmake,所以直接使用就好。
定位到想要编译的模块的文件夹下,比如我们编译qtdeclarative,这其中包含qml模块
cd ~/raspi/raspi-qt-5125/qtdeclarative
~/raspi/qt5pi-host/bin/qmake
//或者
sudo ~/raspi/qt5pi-host/bin/qmake
make -j4
make install
最后同步到树莓派
cd ~/raspi
rsync -avz qt5pi pi@raspberrypi_ip:/usr/local
[PC]配置qt creator的交叉编译环境
首先要安装qt creator,执行之前下载的.run文件
./qt-opensource-linux-x64-5.12.5.run
安装完成之后,对以下几个选项进行配置(Tools->Options->Kits)
Qt Version使用~/raspi/qt5pi-host/bin下的qmake
Compilers使用我们之前的交叉编译链下的g++和gcc
Debuggers(GDB)使用交叉编译链下的gdb
然后保存kit
我们将编译好的代码传到树莓派端,使用sftp
sftp pi@raspberrypi_ip
put xxxx
在树莓派端执行./xxxx -platform linuxfb,其中-platform linuxfb是指定平台