搭建准备:
1.装有Ubuntu16.04的pc一台
2.树莓派的镜像一个
安装树莓派的桌面版本,可以直接配置qt环境,此种方法总是卡卡的,所以笔者不太推荐。
sudo apt-get update
sudo apt-get install qt5-default
sudo apt-get install qtcreator
(如果需要支持qml,需要下载qml的开发环境,使用以下命令)
sudo apt-get install qtdeclarative5-dev
直接进入qtcreator
需要自己手动配置构建套件,配置qmake,gcc,g++,gdb。
配置qmake
配置c和c++编译器
配置套件
创建一个GUI程序,运行如下图:
创建一个QtQuick程序,运行失败,如下图:
因为缺少相应的库,输入如下命令:
sudo apt-get install qtdeclarative5-dev
安装完成后,运行如下图:
搭建树莓派qt交叉编译环境(推荐:开发编译速度快)
安装ubuntu,是直接装系统还是使用虚拟机,大家看着办,笔记上虚拟机,笔者使用的系统是ubuntu14.04amd64。
下载树莓派的交叉编译工具链
cd
mkdir ~/work
cd ~/work
sudo apt-get install git
git clone git://github.com/raspberrypi/tools.git
git时间有点漫长,请继续等待,总共约1.3GB(压缩包是800MB)左右,建议去其他地方下。
下载下来后我们直接放到~/work/tools
该工具链中包含了制作镜像的工具,编译器,测试代码等等,其实我们只用到了编译器,因ubuntu是64位的,所以使用x64的,若是32位,则直接使用不带x64尾缀下的即可。
检测下编译器是否运行成功:
将路径引入系统环境变量:
export PATH=$PATH:~/work/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
测试
mkdir ~/work/project/testHello -p
cd ~/work/project/testHello
sudo apt-get install gedit
gedit main.c
输入程序,并退出,保存
#include
int main(int argc, char **argv)
{
printf("Hello, you do it succeed!!!\n");
return 0;
}
然后编译
arm-linux-gnueabihf-g++ main.c
输出a.out,准备放到目标机验证,使用FileZilla(参照FileZilla远程传送)传送a.out文件到是树莓派桌面(树莓派需要启动ssh服务,可参照笔记一,配置树莓派ssh服务)。
下面打开另外一个终端,使用ssh远程登录,作为交叉编译的登录,我们创建测试文件夹,操作树莓派:
mkdir ~/qtProject/testCrossCompile -p
cd ~/qtProject/testCrossCompile
cp ~/Desktop/a.out .
./a.out
输出语句,交叉编译程序成功。
使用FileZilla远程传送文件(使用sftp)
ubunt上安装sftp工具,ubuntu软件中心搜索filezilla并进行安装。
树莓派和ubuntu在同一个局域网,打开filezilla软件,登录树莓派传送
登录成功,可以传送文件了。
挂载树莓派文件系统
此处挂载树莓派文件系统,主要是对qt源码进行交叉编译时,需要的一些头文件和库的依赖。在后面使用qt的qmake交叉编译qt应用程序时,也会依赖一些库,如操作树莓派gpio则需要树莓派自带的本地库。
将《笔记一》下载的树莓派系统2018-03-13-raspbian-stretch.img拷贝到ubuntu的桌面上,操作ubuntu。
mkdir ~/work/img
cd ~/ work /img
mv ~/Desktop/2018-03-13-raspbian-stretch.img .
sudo mkdir /mnt/pi-rootfs
挂载主要分区,使用fdisk –l查看挂载分区(截图为第一次开发使
此处,若offset不对,mount会提示需要指定文件系统格式,所以要fdisk查看。
sudo mount -o loop,offset=$((98304*512)) 2018-03-13-raspbian-stretch.img /mnt/pi-rootfs/
安装ubuntu的qt(需要qmake和qtcreator)
qmake默认会使用系统的qmake,因为版本等问题,可能会直接影响后面qt编译源码出现奇葩错误,所以下载直接可安装的包,并且同时安装了qctreaor用于开发树莓派qt程序的IDE。
sudo apt-get update
sudo apt-get install g++
sudo apt-get install libgl1-mesa-dev
直接安装qt5.9.3
安装完成后,先创建一个gui程序,配置编译构建套并跑起来。
此时如下命令:
ls -l /usr/bin/qmake
可发现连接的文件不存在。
建立软连接
sudo ln -sf /home/yang/Qt5.7.1/5.7/gcc_64/bin/qmake /usr/bin/qmake
检查确认一次
下载qt源码
桌面版本安装了qt5,那么我们就没必要自己配置了,下次也可以直接装qt5,最关键的点是,下载交叉编译的qt源码需要和树莓派对应,我们查看树莓派qt的版本,如下图,树莓派的qt版本是5.7.1。
qt源码在下地址:http://download.qt.io/archive/qt/
下载5.7.1的源码,如果读者版本不一样自己下载对应版本的源码。
将源码拷贝到~/work下,没有该目录就创建。
cd ~/work
tar xvf qt-everywhere-opensource-src-5.7.1.tar.gz
mv qt-everywhere-opensource-src-5.7.1 qt5.7.1
此处配置下系统,如果是32位则无需配置,是64位则需要添加32位支持
sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0
获取交叉编译
git clone https://github.com/darius-kim/cross-compile-tools.git
矫正库文件
cd cross-compile-tools
sudo ./fixQualifiedLibraryPaths /mnt/pi-rootfs/ ~/work/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gcc
配置qt编译参数
下面对qt进行配置
cd ~/work/qt5.7.1/qtbase
./configure -opengl es2 -device linux-rasp-pi-g++ -device-option CROSS_COMPILE=arm-linux-gnueabihf- -sysroot /mnt/pi-rootfs -opensource -confirm-license -optimized-qmake -reduce-exports -release -make libs -prefix /usr/local/qt5pi -hostprefix /usr/local/qt5pi -v
注意:-sysroot是编译时参照的根目录,-prefix是带上sysroot相对参照根目录的目录,而-hostprefix是对于主机系统的目录。所以以上配置路径详解为下:
编译时查找/usr/inclue/test.h头文件,会查找/mnt/pi-rootfs/usr/include/test.h
安装时安装到文件路径(prefix):/mnt/pi-rootfs/usr/local/qt5pi,主要是目标机的库文件,插件等等,会自动分开装为prefix和hostprefixe
安装时安装到文件路径(hostprefix):/usr/local/qt5pi,主要是主机编译用。
配置过程出现错误如下:
切换一个终端查找树莓派下的libglesv2,是有的,如下图
建立一个软连接
cd /mnt/pi-rootfs/usr/lib/arm-linux-gnueabihf
sudo ln -sf libGLESv2.so.2 libGLESv2.so
切回配置qt的终端,继续配置,配置完成
编译并安装qtbase
使用make –j4,make过程也是先前出现g++,后续为arm-linux-gnueabihf-g++。
出现错误,找不到libz.so,librt.so,libm.so,如下图:
经过查看其实是有这三个库的,只是因为他们是符号链接到/usr/lib所以出错了,如下图:
执行指令:
cd /mnt/pi-rootfs/usr/lib/arm-linux-gnueabihf
sudo ln -sf /mnt/pi-rootfs/lib/arm-linux-gnueabihf/libm.so.6 libm.so
sudo ln -sf /mnt/pi-rootfs/lib/arm-linux-gnueabihf/librt.so.1 librt.so
sudo ln -sf /mnt/pi-rootfs/lib/arm-linux-gnueabihf/libz.so.1.2.8 libz.so
继续make -j4,编译完成
安装sudo make install,安装完成,下面编译其他模块,最好按照顺序编,之前笔者一直整体编译,总是出现各种问题,入坑约1天多的时间。
检查qmake
检查qmake是否成功安装(应该是有参数-hostprefix决定,不带sysroot前缀,而prefix带sysroot)。
ls /usr/local/qt5pi/bin/qmake
找到qmake,可以交叉编译其他模块。
先把qmake文件夹复制到/mnt/rasp-pi-roofs/usr/local/qt5pi
sudo cp -arf ~/work/qt5.7.1/qtbase/bin /mnt/rasp-p-rootfs/usr/local/qt5pi/
/mnt/rasp-pi-rootfs/usr/local/qt5pi/bin/qmake -v
在交叉编译其他模块前,验证以下qt交叉编译是否可以成功编译目标机上的程序。
编译目标机程序并运行验证(qml缺少模块,需要编译其他模块)
下面打开qtcreator创建一个工程,来检测是否可以交叉编译。
先配置构建套
主要是qmake最为关键:
创建一个testWidget项目交叉编译。
编译后无法运行,打开终端运行文件并查看文件
表示我们成功了一大半,然后放到树莓派上桌面上运行,如下图:
运行成功,如下图:
编译其他模块
下面,我们编译其他交叉编译的模块,这里笔者将交缠编译所有模块,因为作为开发机全一点比较好,部署时需要哪个就哪个,避免其他项目可能导致的需要重新编模块,对于大部分人,交叉编译都是有点麻烦的。
cd ~/work/qt5.7.1/
/usr/local/qt5pi/bin/qmake
make -j4
sudo make install
重新使用目标平台的qmake扫一遍所有模块(之前qtbase已配置好),然后make,编译。
在编译模块qtdeclarattive过程中,出现错误,如下图:
修改源码
cd ~/work/qt5/qt-everywhere-opensource-src-5.7.1/qtdeclarative/src/qml/qml
gedit qqmlmemoryprofiler.cpp
搜索static bool openLibrary()
在#ifndef QT_NO_LIBRARY上添加一句#define QT_NO_LIBARRY
编译完成
建议多make两次,仅make。
然后make install
至此5.7.1所有源码交叉编译完美完成。
查看prefix目标机,sysroot/prefix,bin是用于宿主机编译目标机的,实际不能直接编,缺少mkspec配置编译器,我们忽略bin目录(以hostprefix为主)。
查看hostprefix主机,主要是编译编译工具。