Qt5.14.2移植到SOM-RK3399开发板
参考这篇文章
1. 主机开发环境
2. 安装aarch64-linux-gnu-g++交叉编译工具
安装交叉编译工具,我选择通过命令行安装,没有选择从官方地址下载。
- 更新软件源和升级更新软件
sudo apt-get update
sudo apt-get upgrade
- 查看有哪些可选的交叉编译工具可供安装
$ sudo apt-cache search aarch64
binutils-aarch64-linux-gnu - GNU binary utilities, for aarch64-linux-gnu target
binutils-aarch64-linux-gnu-dbg - GNU binary utilities, for aarch64-linux-gnu target (debug symbols)
cpp-7-aarch64-linux-gnu - GNU C preprocessor
cpp-aarch64-linux-gnu - GNU C preprocessor (cpp) for the arm64 architecture
g++-aarch64-linux-gnu - GNU C++ compiler for the arm64 architecture
gcc-7-aarch64-linux-gnu-base - GCC, the GNU Compiler Collection (base package)
gcc-aarch64-linux-gnu - GNU C compiler for the arm64 architecture
qemu-system-arm - QEMU full system emulation binaries (arm)
cpp-5-aarch64-linux-gnu - GNU C preprocessor
cpp-6-aarch64-linux-gnu - GNU C preprocessor
cpp-8-aarch64-linux-gnu - GNU C preprocessor
g++-5-aarch64-linux-gnu - GNU C++ compiler
g++-6-aarch64-linux-gnu - GNU C++ compiler
gcc-5-aarch64-linux-gnu - GNU C compiler
gcc-5-aarch64-linux-gnu-base - GCC, the GNU Compiler Collection (base package)
gcc-5-plugin-dev-aarch64-linux-gnu - Files for GNU GCC plugin development.
gcc-6-aarch64-linux-gnu - GNU C compiler
gcc-6-aarch64-linux-gnu-base - GCC, the GNU Compiler Collection (base package)
gcc-6-plugin-dev-aarch64-linux-gnu - Files for GNU GCC plugin development.
gcc-7-plugin-dev-aarch64-linux-gnu - Files for GNU GCC plugin development.
gcc-8-aarch64-linux-gnu-base - GCC, the GNU Compiler Collection (base package)
gcc-8-plugin-dev-aarch64-linux-gnu - Files for GNU GCC plugin development.
gccgo-5-aarch64-linux-gnu - GNU Go compiler
gccgo-6-aarch64-linux-gnu - GNU Go compiler
gccgo-7-aarch64-linux-gnu - GNU Go compiler
gccgo-8-aarch64-linux-gnu - GNU Go compiler
gccgo-aarch64-linux-gnu - Go compiler (based on GCC) for the arm64 architecture
gdc-5-aarch64-linux-gnu - GNU D compiler (version 2)
gdc-6-aarch64-linux-gnu - GNU D compiler (version 2)
gdc-aarch64-linux-gnu - GNU D compiler (based on GCC) for the arm64 architecture
gfortran-5-aarch64-linux-gnu - GNU Fortran compiler
gfortran-6-aarch64-linux-gnu - GNU Fortran compiler
gfortran-7-aarch64-linux-gnu - GNU Fortran compiler
gfortran-8-aarch64-linux-gnu - GNU Fortran compiler
gfortran-aarch64-linux-gnu - GNU Fortran 95 compiler for the arm64 architecture
gnat-5-aarch64-linux-gnu - GNU Ada compiler
gnat-5-sjlj-aarch64-linux-gnu - GNU Ada compiler (setjump/longjump runtime library)
gnat-6-aarch64-linux-gnu - GNU Ada compiler
gnat-6-sjlj-aarch64-linux-gnu - GNU Ada compiler (setjump/longjump runtime library)
gnat-7-aarch64-linux-gnu - GNU Ada compiler
gnat-7-sjlj-aarch64-linux-gnu - GNU Ada compiler (setjump/longjump runtime library)
gnat-8-aarch64-linux-gnu - GNU Ada compiler
gnat-8-sjlj-aarch64-linux-gnu - GNU Ada compiler (setjump/longjump runtime library)
gobjc++-5-aarch64-linux-gnu - GNU Objective-C++ compiler
gobjc++-6-aarch64-linux-gnu - GNU Objective-C++ compiler
gobjc++-7-aarch64-linux-gnu - GNU Objective-C++ compiler
gobjc++-8-aarch64-linux-gnu - GNU Objective-C++ compiler
gobjc++-aarch64-linux-gnu - GNU Objective-C++ compiler for the arm64 architecture
gobjc-5-aarch64-linux-gnu - GNU Objective-C compiler
gobjc-6-aarch64-linux-gnu - GNU Objective-C compiler
gobjc-7-aarch64-linux-gnu - GNU Objective-C compiler
gobjc-8-aarch64-linux-gnu - GNU Objective-C compiler
gobjc-aarch64-linux-gnu - GNU Objective-C compiler for the arm64 architecture
pkg-config-aarch64-linux-gnu - manage compile and link flags for libraries for arm64 architecture
qemu-efi - transitional dummy package
qemu-efi-aarch64 - UEFI firmware for 64-bit ARM virtual machines
g++-7-aarch64-linux-gnu - GNU C++ compiler (cross compiler for arm64 architecture)
gcc-7-aarch64-linux-gnu - GNU C compiler (cross compiler for arm64 architecture)
g++-8-aarch64-linux-gnu - GNU C++ compiler (cross compiler for arm64 architecture)
gcc-8-aarch64-linux-gnu - GNU C compiler (cross compiler for arm64 architecture)
gdc-7-aarch64-linux-gnu - GNU D compiler (version 2) (cross compiler for arm64 architecture)
gdc-8-aarch64-linux-gnu - GNU D compiler (version 2) (cross compiler for arm64 architecture)
- 安装g+±aarch64-linux-gnu
sudo apt-get install g++-aarch64-linux-gnu
- 查看aarch64-linux-gnu-g++安装到了哪里
$ which aarch64-linux-gnu-g++
/usr/bin/aarch64-linux-gnu-g++
- 查看aarch64-linux-gnu-g++安装的版本
$ aarch64-linux-gnu-g++ -v
Using built-in specs.
COLLECT_GCC=aarch64-linux-gnu-g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/aarch64-linux-gnu/7/lto-wrapper
Target: aarch64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=aarch64-linux-gnu --program-prefix=aarch64-linux-gnu- --includedir=/usr/aarch64-linux-gnu/include
Thread model: posix
gcc version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04)
3. 移植Qt
3.1 修改Qt源码中的Makefile说明文档目录
- 进入mkspecs目录
$ cd Code/qtsourcecode/qt-everywhere-src-5.14.2/qtbase/mkspecs/
- 新建目录linux-arm-som-rk3399
$ mkdir linux-arm-som-rk3399
- 将linux-aarch64-gnu-g++目录中的两个文件qmake.conf和qplatformdefs.h拷贝到linux-arm-som-rk3399目录中
$ cp linux-aarch64-gnu-g++/* linux-arm-som-rk3399/
- 修改linux-arm-som-rk3399/qmake.conf文件
qmake.conf文件的原始文件内容:
#
# qmake configuration for building with aarch64-linux-gnu-g++
#
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
# modifications to g++.conf
QMAKE_CC = aarch64-linux-gnu-gcc
QMAKE_CXX = aarch64-linux-gnu-g++
QMAKE_LINK = aarch64-linux-gnu-g++
QMAKE_LINK_SHLIB = aarch64-linux-gnu-g++
# modifications to linux.conf
QMAKE_AR = aarch64-linux-gnu-ar cqs
QMAKE_OBJCOPY = aarch64-linux-gnu-objcopy
QMAKE_NM = aarch64-linux-gnu-nm -P
QMAKE_STRIP = aarch64-linux-gnu-strip
load(qt_config)
qmake.conf修改后的文件内容:
#
# qmake configuration for building with aarch64-linux-gnu-g++
#
MAKEFILE_GENERATOR = UNIX
CONFIG += incremental
QMAKE_INCREMENTAL_STYLE = sublib
QT_QPA_DEFAULT_PLATFORM = linuxfb
QMAKE_CFLAGS_RELEASE += -O2 -march=armv8-a -lts
QMAKE_CXXFLAGS_RELEASE += -O2 -march=armv8-a -lts
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
# modifications to g++.conf
QMAKE_CC = aarch64-linux-gnu-gcc
QMAKE_CXX = aarch64-linux-gnu-g++
QMAKE_LINK = aarch64-linux-gnu-g++
QMAKE_LINK_SHLIB = aarch64-linux-gnu-g++
# modifications to linux.conf
QMAKE_AR = aarch64-linux-gnu-ar cqs
QMAKE_OBJCOPY = aarch64-linux-gnu-objcopy
QMAKE_NM = aarch64-linux-gnu-nm -P
QMAKE_STRIP = aarch64-linux-gnu-strip
load(qt_config)
4. 编译Qt5.14.2源码
4.1 创建编译Qt5.14.2源码的影子构建目录
创建影子构建目录的目的是:避免直接在Qt源码目录的根目录直接运行configure命令行工具污染源码
- 在Qt源码目录的上一级目录创建目录shadow_build_qt_5.14.2
$ mkdir shadow_build_qt_5.14.2
4.2 创建并编辑自动配置脚本
- 进入shadow_build_qt_5.14.2目录,然后创建一个自动配置脚本auto.sh
$ cd shadow_build_qt_5.14.2
$ touch auto.sh
- 编辑auto.sh,内容如下:
#!/bin/bash
../qt-everywhere-src-5.14.2/configure \
-xplatform linux-arm-som-rk3399 \
-prefix /home/bruce/Code/qtsourcecode/shadow_build_qt_5.14.2/sysbase/qt5.14.2_install \
-release -opensource -confirm-license \
-make libs \
-pch \
-qt-libjpeg \
-qt-libpng \
-qt-zlib \
-no-opengl \
-no-sse2 \
-no-openssl \
-no-cups \
-no-glib \
-no-dbus \
-no-xcb \
-no-separate-debug-info \
-c++std c++17 \
- 给auto.sh添加可执行权限
$ sudo chmod a+x auto.sh
- 执行auto.sh配置Qt源码
$ ./auto.sh
4.3 执行make编译qt源码
$ make -j4
4.3 执行make install安装qt
执行make install后安装到了shadow_build_qt_5.14.2/sysbase/qt5.14.2_install目录
$ cd ~/Code/qtsourcecode/shadow_build_qt_5.14.2/sysbase/qt5.14.2_install
$ ls
bin doc include lib mkspecs plugins qml
5. 确保网络的连通
5.1 配置虚拟机网络配置
我使用笔记本开发的,在笔记本上使用VirtualBox虚拟了Ubuntu18.0.4系统,通过无限网路可以连接到因特网
为了使Ubuntu也能上网,网络配置只能是使用如下图所示:(其他连接方式不能上网)
现在Ubuntu中只有一个无限网卡虚拟的网口,为了和SOM-RK3399开发板通过网线连通,则需要再配置一个网卡2,配置的连接方式如下:
5.2 配置Ubuntu18.04的以太网口的IP
5.3 打开Windows系统网络连接配置以太网口的IP
将其配置为如下IP,保证和SOM-RK3399板子在同一网段
5.4 配置SOM-RK3399板子的IP
- 右键单击无线网络信号标志,选择"Edit Connections…"菜单
- 选择以太网口eth0
- 配置以太网口eth0的IP地址(只需要配置Address,Netmask是自动设置的)
- 命令行查看以太网口eth0的IP
6. SOM-RK3399 NFS网络文件系统环境搭建
6.1 在UBuntu18.04上搭建NFS服务器
6.1.1 安装NFS Server
sudo apt-get install nfs-kernel-server
6.1.2 配置NFS Server,它的配置文件是/etc/exports
创建NFS共享目录som_rk3399_nfs
$ mkdir /home/bruce/Code/Projects/som_rk3399_nfs
$ cd /home/bruce/Code/Projects
设置共享文件夹的权限
$ sudo chmod -R 777 som_rk3399_nfs
设置共享文件夹的所有者
sudo chown bruce:bruce som_rk3399_nfs/ -R
6.1.3 编辑/etc/exports文件
# /etc/exports: the access control list for filesystems which may be exported
# to NFS clients. See exports(5).
#
# Example for NFSv2 and NFSv3:
# /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check)
#
# Example for NFSv4:
# /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check)
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/home/bruce/Code/Projects/som_rk3399_nfs *(rw,sync,no_root_squash)
- /home/bruce/Code/Projects/som_rk3399_nfs: 就是要共享的目录
- "*":代表允许所有的网络段访问
- rw:表示的是可读可写的访问权限
- sync: 表示的是资料同步写入内存和硬盘
- no_root_squash:是Ubuntu nfs 客户端共享目录使用者的权限,如果客户端使用的是root 用户,那么对于该共享目录而言,该客户端就具有root 权限
6.1.4 重启NFS服务(每次修改/etc/exports文件后都需要重新启动 NFS 服务)
sudo /etc/init.d/nfs-kernel-server restart
6.1.5 在UBuntu18.04本机上测试搭建的NFS服务器是否成功
将共享目录挂载到UBuntu18.04本机上的/mnt目录,随便在som_rk3399_nfs目录中或者/mnt中创建一个文件,看som_rk3399_nfs目录和/mnt中是否都存在.
192.168.1.10是Ubuntu主机的IP地址。或者使用localhost(127.0.0.1)测试
$ sudo mount -t nfs 192.168.1.100:~/Code/Projects/som_rk3399_nfs /mnt -o nolock #(注意:这种方式是不行的,必须使用绝对路径使用~挂载会失败,输出如下的内容:)
mount.nfs: access denied by server while mounting localhost:~/Code/Projects/som_rk3399_nfs
$ sudo mount -t nfs localhost:/home/bruce/Code/Projects/som_rk3399_nfs /mnt -o nolock
6.1.6 卸载挂载的共享目录
$ sudo umount /mnt
6.2 在SOM-RK3399开发板上挂载UBuntu18.04上的NFS服务器的共享目录
在SOM-RK3399开发板上,我烧写的是FriendlyELEC系统。
6.2.1 在SOM-RK3399开发板的FriendlyELEC系统上安装NFS服务
$ sudo apt-get update
$ sudo apt-get install nfs-kernel-server
6.2.2 重启NFS服务
pi@SOM-RK3399v2:~$ sudo /etc/init.d/nfs-kernel-server restart
[ ok ] Restarting nfs-kernel-server (via systemctl): nfs-kernel-server.service.
6.2.3 测试和Ubuntu18.0.4的网络是否连通
Ubuntu18.0.4的主机的IP是192.168.1.100,SOM-RK3399板子的IP地址是192.168.1.10,它们之间是通过一根网线连接的。
在SOM-RK339开发板上ping Ubuntu18.04(可以ping通,如下图所示)
6.2.4 将Ubuntu18.0.4上的共享目录som_rk3399_nfs挂载到开发板上
$ mkdir /home/pi/mountHost
$ sudo mount -t nfs 192.168.1.100:/home/bruce/Code/Projects/som_rk3399_nfs /home/pi/mountHost -o nolock
6.2.4 编辑SOM-RK3399的/etc/fstab文件,使开机自动挂载NFS服务器共享目录
默认FriendlyELEC的/etc/fstab文件是空的,现在添加如下内容,使开启SOM-RK3399开发板时自动挂载共享目录
pi@SOM-RK3399v2:~$ cat /etc/fstab
192.168.1.100:/home/bruce/Code/Projects/som_rk3399_nfs /home/pi/mountHost nfs defaults 0 0
pi@SOM-RK3399v2:~$
7. 在SOM-RK3399开发板上安装sshd
pi@SOM-RK3399v2:~$ sudo apt-get install ssh
7.1 重启sshd服务
pi@SOM-RK3399v2:~$ service sshd start
或
/etc/rc.d/init.d/sshd restart
7.2 打开MobaXterm连接开发板
8. 配置Ubuntu18.04上的Qt开发环境
打开Qt Creator选择Tools–>Options
8.1 配置编译器
- 配置g++编译器
- 配置gcc编译器
8.2 配置Qt的版本
选择的是自己编译Qt源码安装目录下的qmake
8.3 配置build套件
9. 配置SOM-RK3399板子上的开发环境
9.1 打包交叉编译的Qt5.14.2
bruce@bruce:~/Code/qtsourcecode/shadow_build_qt_5.14.2/sysbase$ ls qt5.14.2_install
bin doc include lib mkspecs plugins qml
bruce@bruce:~/Code/qtsourcecode/shadow_build_qt_5.14.2/sysbase$ tar -cvzf qt5.14.2_install.tar.gz qt5.14.2_install/
9.2 将qt5.14.2_install.tar.gz 拷贝到共享目录
$ cp qt5.14.2_install.tar.gz ~/Code/Projects/som_rk3399_nfs/
9.3 将qt5.14.2_install.tar.gz解压到SOM-RK339开发板上的/opt目录
pi@SOM-RK3399v2:~/mountHost$ sudo tar -xvf qt5.14.2_install.tar.gz -C /opt
pi@SOM-RK3399v2:~/mountHost$ ls /opt/qt5.14.2_install/
bin doc include lib mkspecs plugins qml
9.4 编辑/etc/profile,配置QT环境变量
将原有内容注释掉,修改为如下内容
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
if [ "${PS1-}" ]; then
if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
# The file bash.bashrc already sets the default PS1.
# PS1='\h:\w\$ '
if [ -f /etc/bash.bashrc ]; then
. /etc/bash.bashrc
fi
else
if [ "`id -u`" -eq 0 ]; then
PS1='# '
else
PS1='$ '
fi
fi
fi
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
#QTDIR=/usr/local/Trolltech/Qt-5.10.0-rk64one
#QT_QPA_PLATFORM=xcb
#QT_QPA_EGLFS_HIDECURSOR=0
#QTWEBENGINE_DISABLE_SANDBOX=1
#QT_QPA_FONTDIR=/usr/share/fonts/truetype/ubuntu-font-family
#QT_QPA_PLATFORM_PLUGIN_PATH=/usr/local/Trolltech/Qt-5.10.0-rk64one/plugins/
export QTDIR=/opt/qt5.14.2_install
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH
export QT_QPA_PLATFORM_PLUGIN_PATH=$QTDIR/plugins
export QT_QPA_PLATFORM=linuxfb
export QT_QPA_FONTDIR=/usr/share/fonts/truetype/ubuntu-font-family
10. 测试
10.1 在Ubuntu18.0.4打开QCreator创建一个测试工程
10.2 在主界面添加一个按钮并实现一个槽用来更改按钮的文本
按钮相应clicked()的槽
void MainWindow::on_testButton_clicked()
{
auto curtext = this->ui->testButton->text();
if(curtext == tr("点击---"))
this->ui->testButton->setText(tr("点击+++"));
else
this->ui->testButton->setText(tr("点击---"));
}
10.3 在Ubuntu18.04上只编译Qt测试工程
执行qmake
编译代码
10.4 将编译成功的可执行文件test_som_rk3399拷贝到共享目录
bruce@bruce:~/Code/Projects/som_rk3399_nfs$ ls
test_som_rk3399