前言

寒假有个在Rockchip RV1126上使用QT开发图形可视化的需求,接到板子之后一边学习QT一边尝试在开发板上部署 QT 应用,暑假的时候已经编译过 SDK (因为这个埋了个大坑),最后发现,如果编译正确的SDK没有问题的话,问题也确实解决一半了。
实现的方法有两种:1、直接在 Builroot 下编译QT应用、2、使用交叉编译工具链编译QT
实践证明两种方法都是可行的,如果只是单纯部署QT应用的话,建议用1,流程简单,如果要做QT应用开发的话,个人建议用2,流程虽然复杂,但是方便后面开发(折腾),各位看官视己情况选择,下面正式开始。

一、Windows 下QT环境搭建

如果你的电脑还没有安装QT Creator的话,请参考: Windows10下QT creator 安装教程
推荐一个QT学习课程:《Qt 5.9 C++开发指南》2021完整版

QT项目文件结构:

在这里插入图片描述

二、在 Builroot 下编译QT应用

参考官方文档:docs/Linux/ApplicationNote/Rockchip_Developer_Guide_Linux_Qt_CN.pdf
我的SDK下载地址:Firefly 资料下载

没有文档可以点击这里下载给我加点积分(狗头);
开玩笑的啦,其实我最讨厌下载东西还要积分啥的(苦笑)百度云链接 提取码:j6xo

我的SDK编译环境是搭建在 WSL (安装教程)下的(首次编译耗时…保守点两个星期,还涉及后面的交叉编译),这个环境搭建教程后续可能会出(大概是我换电脑的时候):)

注意!!!一定要编译对应你们开发板的SDK,完整地编译,不然后面的后面甚至出现不报错但是没有文件生成的错误!我拿到过两个都是rv1109/rv1126的SDK的,但是里面的文件会有所不同,细节导致成败!

1.Buildroot下构建QT工程

在 Buildroot 中添加Qt工程 ,下面介绍添加进Buildroot的方法。
在 SDK/buildroot/package/rockchip/ 目录下,新建你的工程文件夹(QT Creator创建的项目名称,我的项目名称是TextEditor,下文提到的项目名称都是指这个),在文件夹中添加两个文件, Config.in 和 项目
文件名.mk 。

Config.in文件内容如下:

config BR2_PACKAGE_TEXTEDITOR
	bool "TextEditor"
	help
		cgy qt demo

项目名称.mk的内容如下:

################################################################################
#
# TextEditor
#
################################################################################

TEXTEDITOR_VERSION = 1.0
TEXTEDITOR_SITE = $(TOPDIR)/../app/TextEditor
TEXTEDITOR_SITE_METHOD = local

TEXTEDITOR_LICENSE = Apache V2.0
TEXTEDITOR_LICENSE_FILES = NOTICE
define TEXTEDITOR_CONFIGURE_CMDS
cd $(@D); $(TARGET_MAKE_ENV) $(HOST_DIR)/bin/qmake
endef
define TEXTEDITOR_BUILD_CMDS
$(TARGET_MAKE_ENV) $(MAKE) -C $(@D) 
endef

define TEXTEDITOR_INSTALL_TARGET_CMDS
$(INSTALL) -D -m 0755 $(@D)/TextEditor $(TARGET_DIR)/usr/bin/TextEditor
endef
$(eval $(generic-package))

2.移植源码

在添加Buildroot后,你需要把你的工程资源文件夹添加到SDK中去编译,下面介绍添加源码的方法。
在SDK/app/目录下建立你的项目文件夹,在建立的项目文件夹中新建 项目名.pro 文件,内容如下:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

RESOURCES += \
    res.qrc

RC_ICONS += AppIcon.ico

然后将刚才介绍的QT资源文件(.h、.cpp、.ui、.qrc)都复制到这个目录下面,别遗漏了图片或者视频或其他资源文件夹

3.编译工程

make TextEditor-rebuild

可能出现错误:

rockchip rv1126 rv1109 facial gate/host/bin/qmake: No such file or directory

这里我编译的时候出现了找不到qmake的错误 ,将上文中的 Config.in 文件中$(HOST_DIR)/bin/qmake更改成SDK下的buildroot/output/firefly_rv1126_rv1109/host/bin/qamke,问题解决;
如果找不到这个文件,你可以选择:1. 去找到正确的SDK重新编译;2.跳到第三小节使用交叉工具链编译QT。

没有报错编译通过的话,会在SDK/buildroot/output/rockchip_rv1126_rv1109_facial_gate/target/usr/bin/目录下生成可执行文件(文件名是你项目的名称)。

三、使用交叉编译工具链编译QT

参考:Linux Qt5.9.X版本下的交叉编译(openssl + sqlite)

如果在不想折腾这个的话,可以直接跳到最后一步

1.准备工作

  • 1、GCC编译官网下载:
    Linaro Releases
    GCC编译包:gcc-linaro-6.5.0-2018.12-x86_64_arm-linux-gnueabihf.tar.xz
    备注:这个编译包看个人的开发环境而定,我这里以该编译工具包为例

    这一步,其实在SDK的prebuilts/gcc/linux-x86/arm目录下有编译工具包,不过需要注意的是用linaro不是arm,很不幸我弄错了,希望你们别踩坑。
    编译工具包

  • 2.OpenSSL官网下载:
    官方下载地址,OpenSSL以下面为例:
    在这里插入图片描述

  • 3.SQLite官网下载
    官方下载地址,这里选择Source Code下的sqlite-autoconf-xxxxxxx.tar.gz(版本随意)

  • 4.QT5官网下载
    官方下载地址,以下图为例:
    QT5

Tip: 在WSL下,可以在官网右键目标压缩包复制下载地址,可以直接下载到本地,例如QT:

wget https://download.qt.io/archive/qt/5.9/5.9.4/single/qt-everywhere-opensource-src-5.9.4.tar.xz

将下载的三个安装包分别解压:

tar -zxvf openssl-1.0.0.tar.gz
tar -zxvf sqlite-autoconf-3370200.tar.gz
tar -xvf qt-everywhere-opensource-src-5.9.4.tar.xz

Tip: 如果想要解压到指定目录,可以在命令行后面加上参数 -C 目标文件夹

准备工作 Complete,下面开始交叉编译。

2.使用编译工具包进行交叉编译

1.编译OpenSSL

在解压后的OpenSSL目录下执行以下命令,opennssl_build_path为安装路径,自行修改:

./Configure linux-armv4 no-asm shared --prefix=opennssl_build_path

修改OpenSSL目录下的Makefile文件,62行:
修改CC、AR、RANLIB、NM、MAKEDEPPROG参数,将其修改成上文中编译工具包的路径,如下图所示是我的路径,MAKEDEPPROG的路劲和CC的一样

编译工具包
OpenSSL目录下Makefile文件62行开始:
修改Makefile文件

注意!!!这些路径一定要设置正确!不然编译QT步骤时,运行build.sh脚本时会出现错误。

最后执行命令进行编译:

make -j4
make install

可能出现的错误:
OpenSSL编译错误
解决方法,将这个/usr/bin/pod2man删掉,再编译:

rm /usr/bin/pod2man

编译安装好,进去你所安装的目录下,执行以下命令检查是否交叉编译成功:

file ./lib/libcrypto.so.1.0.0

成功会打印出以下信息:

./lib/libcrypto.so.1.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=4d397b8e162dd9553787aa0cf733e82f27d2db6a, not stripped

Tip: 建议编译安装路径设置成绝对路径,相对路径可能会出现路径错误的问题 :)

2.编译SQLite

同上,在解压后的SQLite目录下执行以下命令,sqlite_build_path为安装路径,gcc_path为GCC编译器路径,自行修改:


./configure --prefix=sqlite_build_path --host=arm-linux-gnueabihf CC=gcc_path/arm-linux-gnueabihf-gcc

然后SQLite目录下执行以下命令:

make -j4
make install

成功后显示:

----------------------------------------------------------------------
Libraries have been installed in:
   /home/ethan/sqlite_build/lib

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the '-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the 'LD_RUN_PATH' environment variable
     during linking
   - use the '-Wl,-rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to '/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
 /usr/bin/mkdir -p '/home/ethan/sqlite_build/bin'
  /bin/bash ./libtool   --mode=install /usr/bin/install -c sqlite3 '/home/ethan/sqlite_build/bin'
libtool: install: /usr/bin/install -c sqlite3 /home/ethan/sqlite_build/bin/sqlite3
 /usr/bin/mkdir -p '/home/ethan/sqlite_build/include'
 /usr/bin/install -c -m 644 sqlite3.h sqlite3ext.h '/home/ethan/sqlite_build/include'
 /usr/bin/mkdir -p '/home/ethan/sqlite_build/share/man/man1'
 /usr/bin/install -c -m 644 sqlite3.1 '/home/ethan/sqlite_build/share/man/man1'
 /usr/bin/mkdir -p '/home/ethan/sqlite_build/lib/pkgconfig'
 /usr/bin/install -c -m 644 sqlite3.pc '/home/ethan/sqlite_build/lib/pkgconfig'
make[1]: Leaving directory '/home/ethan/sqlite-autoconf-3370200'

3.编译QT

进入解压QT的目录下,新建build.sh文件,opennssl_build_path为OpenSSL安装路径,sqlite_build_path为SQLite安装路径,qt_build_path为将要安装的QT目录,自行修改内容如下:

#!/bin/sh
OPENSSL_LIBS='-Lopennssl_build_path/lib -lssl -lcrypto'
./configure -prefix qt_build_path \
-opensource \
-debug \
-confirm-license \
-xplatform linux-arm-gnueabi-g++ \
-pch \
-linuxfb \
-no-opengl \
-shared \
-no-iconv \
-no-xcb \
-sqlite \
-qt-zlib \
-openssl-linked -I opennssl_build_path/include -L opennssl_build_path/lib \
-recheck-all

然后移动到解压QT目录执行以下命令:

cd qtbase/mkspecs/linux-arm-gnueabi-g++

修改qmake.conf文件,内容如下,openssl_build_path为OpenSSL安装路径,sqlite_build_path为SQLite安装路径,compiler_path为编译器路径,自行修改:

#
# qmake configuration for building with arm-linux-gnueabi-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)
 
QT_QPA_DEFAULT_PLATFORM=linuxfb
QMAKE_INCDIR += sqlite_build_path/include openssl_build_path/include
QMAKE_LIBDIR += sqlite_build_path/lib openssl_build_path/lib
 
# modifications to g++.conf
#根据自己的GCC编译器路径来定
QMAKE_CC                = compiler_path/arm-linux-gnueabihf-gcc
QMAKE_CXX               = compiler_path/arm-linux-gnueabihf-g++
QMAKE_LINK              = compiler_path/arm-linux-gnueabihf-g++
QMAKE_LINK_SHLIB        = compiler_path/arm-linux-gnueabihf-g++
 
# modifications to linux.conf
QMAKE_AR                = compiler_path/arm-linux-gnueabihf-ar cqs
QMAKE_OBJCOPY           = compiler_path/arm-linux-gnueabihf-objcopy
QMAKE_NM                = compiler_path/arm-linux-gnueabihf-nm -P
QMAKE_STRIP             = compiler_path/arm-linux-gnueabihf-strip
load(qt_config)

修改完成后,回到解压QT的目录,执行以下命令:

chmod +x build.sh
./builsh.sh

可能会出现的错误:

ERROR: Feature 'openssl-linked' was enabled, but the pre-condition '!features.securetransport && libs.openssl' failed.

解决方法:
出现这个错误说明你的OpenSSL没有安装成功,请回到OpenSSL安装步骤检查你的Makefile文件各个参数的路径有没有问题,不关版本的事情

脚本运行成功后,会打印出以下信息:

Note: Also available for Linux: linux-clang linux-icc

Note: When linking against OpenSSL, you can override the default
library names through OPENSSL_LIBS.
For example:
    OPENSSL_LIBS='-L/opt/ssl/lib -lssl -lcrypto' ./configure -openssl-linked

Note: No wayland-egl support detected. Cross-toolkit compatibility disabled.

Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into '/home/ethan/qt_build'.

Prior to reconfiguration, make sure you remove any leftovers from
the previous build.

看到以上信息证明运行成功, 执行编译命令:

make -j4
make install

编译安装成后,控制台会打印以下结果:

make[2]: Leaving directory '/home/ethan/qt-everywhere-opensource-src-5.9.4/qttranslations/translations'
make[1]: Leaving directory '/home/ethan/qt-everywhere-opensource-src-5.9.4/qttranslations'
cd qtdoc/ && ( test -e Makefile || /home/ethan/qt-everywhere-opensource-src-5.9.4/qtbase/bin/qmake -o Makefile /home/ethan/qt-everywhere-opensource-src-5.9.4/qtdoc/qtdoc.pro ) && make -f Makefile install
make[1]: Entering directory '/home/ethan/qt-everywhere-opensource-src-5.9.4/qtdoc'
cd doc/ && ( test -e Makefile || /home/ethan/qt-everywhere-opensource-src-5.9.4/qtbase/bin/qmake -o Makefile /home/ethan/qt-everywhere-opensource-src-5.9.4/qtdoc/doc/doc.pro ) && make -f Makefile install
make[2]: Entering directory '/home/ethan/qt-everywhere-opensource-src-5.9.4/qtdoc/doc'
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/home/ethan/qt-everywhere-opensource-src-5.9.4/qtdoc/doc'
make[1]: Leaving directory '/home/ethan/qt-everywhere-opensource-src-5.9.4/qtdoc'

4.使用qmake编译 QT 应用

参考:WSL2环境下交叉编译QT工程,开发板成功运行(全过程详解)

  • 1.将你的QT creator 创建的项目文件夹直接复制到WSL下面;

  • 2.删除后缀为.pro.user文件(防止出错,我没删也没报错);

  • 3.在项目文件夹下面执行执行命令,qt_build_path为你刚才QT安装设置的路径:

    qt_buid_path/qmake
    
  • 4.上一步成功后会在该目录下生成Makefile文件,执行命令编译项目:

    make
    

编译成功后会在该目录下生成可执行文件。

Tip: 在资源管理器地址栏中输入:\\wsl$ 可直接打开WSL系统文件夹

四、上机测试

1.将可执行文件复制到开发板上进行测试

怎么传输式各位看官觉得啥方便就用啥,小小白:ssh使用scp传输文件adb传输文件串口传输文件

2.配置环境变量

进入rv1126命令行,执行以下命令:

export QT_QPA_FB_DRM=1
export QT_QPA_PLATFORM=linuxfb:rotation=0

不设置可能会出现错误:

This application failed to start because it could not find or load the Qt platform plugin "eglfs"
in "".

Available platform plugins are: linuxfb, minimal, offscreen, vnc.

Reinstalling the application may fix this problem.
Aborted (core dumped)

3.添加权限并执行程序

chmod +x TextEditor
./TextEditor

实现效果图:
在 Builroot 下编译:
builroot
交叉编译工具编译QT后使用qmake编译:
Qmake

大功告成!

五、其他问题及解决方法

编译SDK时可能出现的问题:

1.用户身份问题

you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment to bypass this

解决方法:

export FORCE_UNSAFE_CONFIGURE=1

参考:编译错误you should not run configure as root (set FORCE_UNSAFE_CONFIGURE=1 in environment to bypass this

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐