1.为什么厂家buildroot编译出来的Qt不能通用

  • 与busybox不同,buildroot 不仅集成了 busybox,而且还集成了各种常见的第三方库和软件,需要什么就选择什么,buildroot 会帮我们处理好各种细节,根文件系统也会更加的合理、有效。
  • 但是厂家的buildroot编译脚本指定了编译路径,有些路径是根本不存在的,根本不会在该路径下生成Qt编译文件,很有可能厂家构建这一切用的虚拟机与提供给客户的不是同一个,如下图为Qt Creator搭建交叉编译环境时的提示。

  • 之后,我查看qmake文件的hex编码,发现有些路径根本就不存在,要么是路径下没有相关文件。

  • 尝试在该路径下复制文件也是无效的。

2.为什么我们自己编译Qt很容易失败

  • 在linux下有些编译器,依赖之类,他会随着版本更新变化,然而有些过去依靠他们老版本制作的文件,比如旧版Qt源文件,在我们的环境更新后会出现某些语法问题、引用问题之类,这种问题让人无奈又头疼,比如从下面这些错误可见一斑,只能尝试一点点去解决这些问题。

3.Qt开发具体流程

3.1前提:确保交叉编译环境

  • 在命令行输入下面的命令验证是否有交叉编译环境,确认无误才可以编译。
    arm-linux-gnueabihf-gcc -v

3.2 下载Qt官方源码

  • 进入下面的网址下载Qt源码,我们开发板用的是5.9版本,所以linux平台源码也要用5.9的,原则上应该可以下载低于5.9版本的,应该可以向下兼容,但是不能下载高版本的,为避免有问题,最好下载对应版本。
    https://download.qt.io/archive/qt/

3.2编辑qtbase/mkspecs/qws/linux-arm-gnueabi-g++/qmake.conf,配置相关编译器及路径。

  • 这个配置cortex-a7是通用的,imx6ull也是一样的。

3.3配置编译选项,即选择开启关闭哪些功能,此处是最容易出错的地方,配置有问题会导致后面的编译失败,有些问题只有作者才能解决。

  • 我这里通过的编译选项为:
    1
    ./configure -release -nomake examples -no-iconv -no-opengl -no-assimp -no-qt3d-profile-jobs -no-qt3d-profile-gl -xplatform linux-arm-gnueabi-g++ -prefix home/gzpeite/qt-everywhere-opensource-src-5.9.0/arm-qt  -opensource  -confirm-license
  • 也可以编写脚本,直接运行脚本即可,这里指定了我们自己的路径,肯定不会有问题。

3.4 交叉编译生成Arm下的qmake

  • 执行完成上面的配置之后,就可以开始编译Qt,编译时间长且容易受到配置的影响导致失败,所以一般编译失败都可以看看是不是配置项哪里有问题。
  • 执行make命令 (可以多线程make -j4,代表4线程,具体看虚拟机和电脑配置)
    如果编译正常没有错误,此时可以make install,将其安装到我们在配置中指定的路径中去。

3.4移植Qt到开发板文件系统(A40i可省略此步骤,因其可以在buildroot构建)

  • 将上面生成的arm-qt文件打包,通过U盘拷贝到文件系统中,比如usr/local/这个路径下面,然后配置Qt5的环境变量,编辑/etc/profile文件。
    1
    2
    3
    4
    5
    6
    export QT_ROOT=/usr/local/arm-qt 
    export QT_QPA_PLATFORM_PLUGIN_PATH=$QT_ROOT/plugins
    export QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0
    export QT_PLUGIN_PATH=$QT_ROOT/plugins
    export LD_LIBRARY_PATH=$QT_ROOT/lib:$QT_ROOT/plugins/platforms
    export QML2_IMPORT_PATH=$QT_ROOT/qml
  • 至此,Qt编译完成,下面开始安装Qt Creator,编写程序测试环境。

3.5安装Qt Creator

  • 下载 qt-opensource-linux-x64-5.9.0.run 这个文件。

  • 赋予该文件可执行权限,再执行安装。

    1
    2
    chmod u+x qt-opensource-linux-x64-5.9.0.run  
    sudo ./qt-opensource-linux-x64-5.9.0.run

  • 安装时需要用邮箱在Qt官网注册一下,按要求做即可。具体安装过程不在赘述,默认安装即可,linux又不分盘。

3.6为Qt Creator创建Arm开发环境

  • 打开tools ->Optons

  • 配置qmake为之前编译的Arm下qmake

  • 配置C++编译器为Arm交叉编译器,Qt是C++语言,C编译器可以不配置

  • 配置Kits,选择我们配置好的Compiler和Qt Version即可。

  • 至此,环境配置完成。

3.7新建项目,编写Qt程序

  • 通过命令行,或者搜索Qt打开

  • 新建项目,一定要选择上面构建的arm-qt编译环境

  • 这里一定要选上

  • 编写Qt测试程序,查看其是否能在Arm环境下运行

  • 注意,因为其有两套编译环境,arm-qt是在开发板运行的,另外一个Desktop Qt 5.9.0 GCC 64bit是在linux下运行的,想要程序在开发板上运行,一定要用arm-qt去构建编译项目。

  • 编译完成之后,会在项目下生成Debug目录,只有Arm-qt里面的可执行文件test才是我们开发板需要的

3.8拷贝test文件到开发板去运行

  • 执行 ./test命令

  • 可以看到,两个环境均没有问题,Qt程序正常运行。

3.9OpenCV的编译过程很简单,CMAKE的GUI配置一下就可以了,这里不再赘述,提供如何在程序里加入OpenCV。

  • 在Qt项目的pro文件里加入如下内容

1
2
3
4
5
6
INCLUDEPATH += /home/gzpeite/opencv-4.6.0/install/include
LIBS += ../../lib/libopencv_core.so \
../../lib/libopencv_highgui.so \
../../lib/libopencv_imgproc.so \
../../lib/libopencv_videoio.so \
../../lib/libopencv_imgcodecs.so
  • 根据需要添加下面的头文件
    1
    2
    3
    4
    #include <opencv2/imgproc/imgproc_c.h> 
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgproc.hpp>
    #include <opencv/cv.h>

QT的pro文件配置opencv库双环境

  • 使用TARGET_ARCH = $${QT_ARCH}获取当前编译器的架构
  • 通过contains(TARGET_ARCH, arm)来做arm与x86环境的区分,用来做库链接设置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0


TARGET_ARCH = $${QT_ARCH}
contains(TARGET_ARCH, arm){

message(">>> Building for ARM platform")

# Qt 路径(ARM)
QTDIR_ARM = /opt/qt5.12.12
INCLUDEPATH += $${QTDIR_ARM}/include
LIBS += -L$${QTDIR_ARM}/lib -lQt5Core -lQt5Widgets -lQt5Gui

PKGCONFIG += opencv
INCLUDEPATH += /home/linux/rk3506/tool/opencv/opencv-4.12.0/install_arm/include/opencv4

LIBS += -L/home/linux/rk3506/tool/opencv/opencv-4.12.0/install_arm/lib \
-lopencv_core \
-lopencv_imgproc \
-lopencv_highgui \
-lopencv_videoio \
-lopencv_imgcodecs \
-lopencv_dnn \
-lopencv_features2d \
-lopencv_calib3d \
-lopencv_flann \
-lopencv_objdetect

# INCLUDEPATH += /opt/qt5.12.12/libinclude
# LIBS += -L/opt/qt5.12.12/lib -lQt5Core -lQt5Widgets -lQt5Gui

} else {

message(">>> Building for Ubuntu host")

# Qt 路径(Ubuntu)
QTDIR_PC = /home/linux/Qt5.12.12/5.12.12/gcc_64
INCLUDEPATH += $${QTDIR_PC}/include
LIBS += -L$${QTDIR_PC}/lib -lQt5Core -lQt5Widgets -lQt5Gui

INCLUDEPATH += /usr/local/include/opencv4
LIBS += -L/usr/local/lib \
-lopencv_core \
-lopencv_imgproc \
-lopencv_highgui \
-lopencv_videoio \
-lopencv_imgcodecs \
-lopencv_dnn \
-lopencv_features2d \
-lopencv_calib3d \
-lopencv_flann \
-lopencv_objdetect

}


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