寒假有个在Rockchip RV1126上使用QT开发图形可视化的需求,接到板子之后一边学习QT一边尝试在开发板上部署 QT 应用,暑假的时候已经编译过 SDK (因为这个埋了个大坑),最后发现,如果编译正确的SDK没有问题的话,问题也确实解决一半了。
实现的方法有两种:1、直接在 Builroot 下编译QT应用、2、使用交叉编译工具链编译QT
实践证明两种方法都是可行的,如果只是单纯部署QT应用的话,建议用1,流程简单,如果要做QT应用开发的话,个人建议用2,流程虽然复杂,但是方便后面开发(折腾),各位看官视己情况选择,下面正式开始。
如果你的电脑还没有安装QT Creator的话,请参考: Windows10下QT creator 安装教程
推荐一个QT学习课程:《Qt 5.9 C++开发指南》2021完整版
QT项目文件结构:
参考官方文档:docs/Linux/ApplicationNote/Rockchip_Developer_Guide_Linux_Qt_CN.pdf
我的SDK下载地址:Firefly 资料下载
没有文档可以点击这里下载给我加点积分(狗头);
开玩笑的啦,其实我最讨厌下载东西还要积分啥的(苦笑)百度云链接 提取码:j6xo
我的SDK编译环境是搭建在 WSL (安装教程)下的(首次编译耗时…保守点两个星期,还涉及后面的交叉编译),这个环境搭建教程后续可能会出(大概是我换电脑的时候):)
注意!!!一定要编译对应你们开发板的SDK,完整地编译,不然后面的后面甚至出现不报错但是没有文件生成的错误!我拿到过两个都是rv1109/rv1126的SDK的,但是里面的文件会有所不同,细节导致成败!
在 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))
在添加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)都复制到这个目录下面,别遗漏了图片或者视频或其他资源文件夹
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/目录下生成可执行文件(文件名是你项目的名称)。
参考:Linux Qt5.9.X版本下的交叉编译(openssl + sqlite)
如果在不想折腾这个的话,可以直接跳到最后一步
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,很不幸我弄错了,希望你们别踩坑。
3.SQLite官网下载
官方下载地址,这里选择Source Code下的sqlite-autoconf-xxxxxxx.tar.gz(版本随意)
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,下面开始交叉编译。
在解压后的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行开始:
注意!!!这些路径一定要设置正确!不然编译QT步骤时,运行build.sh脚本时会出现错误。
最后执行命令进行编译:
make -j4
make install
可能出现的错误:
解决方法,将这个/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: 建议编译安装路径设置成绝对路径,相对路径可能会出现路径错误的问题 :)
同上,在解压后的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'
进入解压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'
参考:WSL2环境下交叉编译QT工程,开发板成功运行(全过程详解)
1.将你的QT creator 创建的项目文件夹直接复制到WSL下面;
2.删除后缀为.pro.user文件(防止出错,我没删也没报错);
3.在项目文件夹下面执行执行命令,qt_build_path为你刚才QT安装设置的路径:
qt_buid_path/qmake
4.上一步成功后会在该目录下生成Makefile文件,执行命令编译项目:
make
编译成功后会在该目录下生成可执行文件。
Tip: 在资源管理器地址栏中输入:\\wsl$ 可直接打开WSL系统文件夹
怎么传输式各位看官觉得啥方便就用啥,小小白:ssh使用scp传输文件、adb传输文件、串口传输文件
进入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)
chmod +x TextEditor
./TextEditor
实现效果图:
在 Builroot 下编译:
交叉编译工具编译QT后使用qmake编译:
大功告成!
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