经过无数次失败总结出如下方法,通过这个方法可以成功进行2017~2019年树莓派官方镜像的交叉编译。我最早使用的2017年的镜像,下文中2017年的镜像交叉编译要简单些,省略下文中opengl es2编译不成功的配置部分。后来手上有了一个 树莓派 3B+板子,2017年的镜像就无法使用了。加上QT最近几年对稳定性进行了大量的优化,使用新版本可以避免很多问题,所以新版本QT升级很有必要。
首先先说下系统的选择,一开始我选择的是Ubuntu 16.04 x64位的系统,这个系统在对Raspbian进行添加链接库有点问题。后来选择使用Ubuntu 14.04 x86 32位系统,最终也可可以编译出正确的qmake的,但是存在一个问题,因为32位的系统也只能选择32位的qt-creator,能找到的版本基本上都是QT5.5之前的版本,高版本都是64位的无法安装。咱们编译出的qmake都是5.9.9版本,后续用QT在linux下设计会受限制。最终还是使用Ubuntu 14.04 x64位系统。QT安装包最终使用的是Qt5.9.6版本,下一篇文章中有详细说明。还有个注意事项需要说明下,QT5.9.6安装包一定要在交叉编译完成之后再进行安装,对本文多次验证基本都成功,但偶尔也有一次的失败,经分析要么是复制文件造成数据缺失、要么是先安装QT5.9.6造成的。
下文中所用到的下载内容,我都进行了打包上传到百度云盘,如果同学在编译过程中遇到阻碍,可以下载下来配合本文进行对比分析。
链接: https://pan.baidu.com/s/1RMU9ojc1H8Y8VScPqEjMgA 提取码: zu6z
第一步 准备镜像文件
选择树莓派的版本http://downloads.raspberrypi.org/raspbian/images/
我们使用的是2019-04-08-raspbian-stretch.img
新建镜像文件挂载路径,新建镜像存放文件夹rpi
sudo mkdir /mnt/rasp-pi-rootfs/
sudo mkdir /mnt/rasp-boot/
mkdir rpi
cd rpi
使用WinSCP工具将文件放入rpi文件夹中,然后查看镜像文件的索引。
fdisk -l 2019-04-08-raspbian-stretch.img
挂载偏移值计算 offset=98304*512=50331648
sudo mount -o offset=50331648 -t ext4 2019-04-08-raspbian-stretch.img /mnt/rasp-pi-rootfs/
挂载boot 同理offset=8192*512= 4194304
sudo mount -o offset=4194304 -t vfat 2019-04-08-raspbian-stretch.img /mnt/rasp-boot/
下文中会用到git工具,我们先安装
sudo apt-get install git
第二步,准备交叉编译链
在/usr/local路径中创建rpi文件夹,进入文件夹后下载树莓派交叉编译链
cd /usr/local
sudo mkdir rpi
cd rpi
sudo git clone git://github.com/raspberrypi/tools.git
没有翻墙加速的话,这个过程会比较慢,可以关屏睡觉了。
另外可以直接使用我分享tools.gz ,如果没有/usr/local/rpi文件夹需要先创建,如下操作。
sudo mkdir /usr/local/rpi
sudo tar zxvf tools.gz -C /usr/local/rpi/
完成后进行查看,我们选择的是gcc-linaro-arm-linux-gnueabihf-raspbian工具链
ls /usr/local/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/
依赖库安装 (32位Ubuntu跳过此步骤)
sudo apt-get install ia32-libs
安装时会弹出如下
依次安装lib32z1 lib32ncurses5,描述是替代库。(32位Ubuntu跳过此步骤)
sudo apt-get install lib32ncurses5
sudo apt-get install lib32z1
sudo apt-get install lib32bz2-1.0
cross-compile-tools需要的库
sudo apt-get install lib32stdc++6
QT编译需要安装的编译链
sudo apt-get install g++
第三步,准备cross-compile-tools工具
这个工具能否编译成功非常关键,我的分享地址,使用WinSCP放入在~/rpi文件中
cd cross-compile-tools/
chmod +x *
sudo ./fixQualifiedLibraryPaths /mnt/rasp-pi-rootfs/ /usr/local/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc
第四步,下载QT源码库并进行编译
cd ~
git clone git://code.qt.io/qt/qt5.git -b 5.9
cd qt5/
./init-repository
这里同学们一定会很奇怪,前面不是已经安装了Qt5.9.9了么,这里为什么还需要下载。前文中我们主要是安装QCreator和linux x86 qmake这两个工具,我们还缺少RaspberryPi的qmake工具,这里是下载Qt5.9源码并且编译出Rpi中的qmake。
这个过程也比较慢,需要耐心等待。如果嫌下载太慢可以使用我的分享,先用WinScp下载到rpi文件中,如下指令进行解压。
cd rpi
tar zxvf qt5.tar.gz -C ~/
从这里到第五步之间的内容可以忽略,记录下来是方便以后遇到类似问题可以知道解决方法。
./configure -opengl es2 -device linux-rasp-pi3-g++ -device-option CROSS_COMPILE=/usr/local/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- -sysroot /mnt/rasp-pi-rootfs/ -opensource -confirm-license -optimized-qmake -reduce-exports -release -make libs -make tools -prefix /usr/local/qt5pi -v -nomake examples -nomake tests
中途会弹出如下错误
重新对编译链进行连接
cd /mnt/rasp-pi-rootfs/usr/lib/arm-linux-gnueabihf
sudo rm libm.so
sudo ln -s ../../../lib/arm-linux-gnueabihf/libm.so.6 libm.so
编译过程弹出错误
这是因为linux-rasp-pi3-g++ 的配置文件qtbase/mkspecs/devices/linux-rasp-pi3-g++/qmake.conf的CPU类型是arm8-a, 我们在树莓派中用如下指令查询一下
uname -a
查看qtbase/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf的配置文件,CPU选择的是arm7-a和我们系统基本一致。
更换设备类型重新编译。
./configure -opengl es2 -device linux-rasp-pi2-g++ -device-option CROSS_COMPILE=/usr/local/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- -sysroot /mnt/rasp-pi-rootfs/ -opensource -confirm-license -optimized-qmake -reduce-exports -release -make libs -make tools -prefix /usr/local/qt5pi -v -nomake examples -nomake tests
这次虽然成功了但是不支持opengl es2 我们需要修改配置文件。
vi qtbase/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf
之前我在2017的树莓派官方镜像,交叉编译过程中是支持openg1 es2的。这次将镜像文件中的/opt/vc/lib/进行比较
cd /mnt/rasp-pi-rootfs
ls opt/vc/lib/ -lh
sudo find -name libEGL*
sudo find -name libGLESv2*
这时发现问题的原因了,使用库时无法找到库文件,按如下方式进行连接。
cd opt/vc/lib/
sudo ln -s ../../../usr/lib/arm-linux-gnueabihf/libEGL.so.1.0.0 libEGL.so
sudo ln -s ../../../usr/lib/arm-linux-gnueabihf/libGLESv2.so.2.0.0 libGLESv2.so
到此时可以测试一下opengl_es2是否可以编译。
如下指令进行测试
cd config.tests/opengl_es2
make clean
make
当如上显示时,表示成功。
下一步开始编译
cd ~/qt5/
./configure -opengl es2 -device linux-rasp-pi2-g++ -device-option CROSS_COMPILE=/usr/local/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- -sysroot /mnt/rasp-pi-rootfs/ -opensource -confirm-license -optimized-qmake -reduce-exports -release -make libs -make tools -prefix /usr/local/qt5pi -v -nomake examples -nomake tests -no-use-gold-linker
小技巧:当提示“make: Nothing to be done for `first'.”并很快编译完成时,说明没有进行重新编译,我们可以将-device linux-rasp-pi2-g++先改成-device linux-rasp-pi-g++编译一次,然后再-device linux-rasp-pi2-g++编译
到此我们终于显示了久未的图13图14
但是这样执行下去,编译出来的qt程序任然无法运行,会提示“Could not initialize egl display”
那么复盘重来
第五步,补充编译链
参考官方手册https://wiki.qt.io/RaspberryPi2EGLFS
发现我们动态链接库存在问题,那么重新进行配置(针对2018~2019的树莓派镜像)
cd /mnt/rasp-pi-rootfs/usr/lib/arm-linux-gnueabihf
sudo mv libEGL.so.1.0.0 libEGL.so.1.0.0_backup
sudo mv libGLESv2.so.2.0.0 libGLESv2.so.2.0.0_backup
sudo ln -s ../../../opt/vc/lib/libEGL.so libEGL.so.1.0.0
sudo ln -s ../../../opt/vc/lib/libGLESv2.so libGLESv2.so.2.0.0
cd /mnt/rasp-pi-rootfs/opt/vc/lib/
sudo ln -s libbrcmEGL.so libEGL.so
sudo ln -s libbrcmGLESv2.so libGLESv2.so
sudo ln -s libEGL.so libEGL.so.1
sudo ln -s libGLESv2.so libGLESv2.so.2
重新编译配置
cd ~/qt5/
./configure -opengl es2 -device linux-rasp-pi2-g++ -device-option CROSS_COMPILE=/usr/local/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- -sysroot /mnt/rasp-pi-rootfs/ -opensource -confirm-license -optimized-qmake -reduce-exports -release -make libs -make tools -prefix /usr/local/qt5pi -v -nomake examples -nomake tests -no-use-gold-linker
到这里没有问题,咱们就成功的一大半了。有过遇到什么问题,请下载我的分享,重新按上述步骤再执行一次,应该可以解决。下面就是QT的源码交叉编译了。
make
sudo make install
最后,镜像烧写
编译和安装完成后,执行一次硬盘同步(注意这一步很关键,保证数据从缓存同步到SD卡中),然后卸除挂载。接入SD卡到虚拟机,向SD卡烧写镜像。
sudo sync
sudo sudo umount /mnt/rasp-pi-rootfs
cd ~/rpi
sudo dd bs=1M if=2019-04-08-raspbian-stretch.img of=/dev/sdb
sudo sync
注意:如果出现烧写完成后系统无法启动时,或卡在挂载点跳转处时多半是镜像烧写不完整问题。可以将镜像复制到windows下通过Win32DiskImager.exe工具烧写。
到这里树莓派QT5.9.9成功交叉编译的镜像已经创建完成,最难的一步已经完成。后续文章会描述QT的环境配置。
下来大家发现有什么问题或需要讨论交流,可以在、博客园、或邮箱将问题进行留言,我会及时回复和更新。
邮箱: [email protected]
原创:https://www.simbahiker.com/news/0220200610001.html