在硬件板卡提供商提供的嵌入式linux平台下的Qt环境中,很多时候会不太适合实际的开发场景:

(1)可能一些Qt的模块不支持。这时候要么找厂家,要么自己编译。

(2)在厂家提供的平台开发环境中,支持的东西太多,太杂,导致整个文件系统镜像太大。这时候为了减小根文件系统,往往需要自己集成和编译开发环境。

(3)不同版本Qt编译构建出的库文件,一般会不兼容,需要针对特定版本进行交叉编译。

本文主要是记录在Qt源码跨平台源码编译构建过程中的一些注意点以及自己的思考。因平台太多,软件环境大多不同,故不会针对特定平台进行详细步骤描述,所以记录些共同点,细节点就略过啦。如果有疑问,可以加小生微信相互交流,互相学习,哈哈!

编译Qt源码,首先就获取源码,从Qt官方网站https://download.qt.io/archive/qt/获取源码。将其解压缩,完成后如下图所示:

从目录结构来观察,源码结构以模块方式高度划分。Qt的各个模块都可以单独编译,当然一般使用最多的是整体编译。在使用工具(例如buildroot)制作嵌入式linux根文件系统时,对Qt部分是自动编译的(暂不清楚里面的构建细节)

在上图中,有一个qtbase目录,该目录是Qt的基础模块目录,该目录下同样有configure文件(在源码目录下也有一个configure配置文件,这两个文件不一样)

在Qt源码目录下执行:

./configure --help

会打印出帮助信息,在/qtbase目录下使用上述命令同样会打印帮助信息,只是在此处打印出的信息比在源码目录下使用confiigure --help命令打印出的帮助信息少。

当我们在Qt源码目录下执行./configure命令时,可以配置整体编译方案,我们则可以在此处设置想要编译构建的参数和模块。

在/qtbase目录下,执行./configure命令时,配置的是在该目录下的Qt基本模块。从源码目录结构,可以知道在qtbase模块下包含许多子模块:

其中包含:core、network、sql、widget等。

只编译构建qtbase,开发运行常见窗体应用是可以的

mkspecs目录

qtbase目录下,存放了多个目录,如下图所示:

因为Qt是跨平台的,在该目录下则存放了许多与具体平台相关的目录,目录的名称则是以具体架构来命名,且目录中存放了两个文件:

  • qmake.conf:该文件是关于具体架构的qmake配置描述,一般内容格式如下:
#
# qmake configuration for building with aarch64-linux-gnu-g++
#MAKEFILE_GENERATOR      = UNIX
CONFIG                 += incremental
QMAKE_INCREMENTAL_STYLE = sublibinclude(../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)
  • qplatformdefs.h:该文件是一个头文件,文件中内容用于描述具体模块层级包含的相关头文件依赖。

qmake.conf是一个重要的文件,在针对具体平台编译构建源码时,可能需要修改该文件下的内容:


在上述图片中,等号右边表示具体的编译构建工具名称。需要提前安装对应的编译套件且将他们添加到环境变量中(如果没有添加,可以以绝对路径来描述)。例如,如果是在linux平台下,且将编译器添加到了环境变量中,可以使用编译器名称加上v参数选项查看编译器信息,此处以交叉编译器aarch64-linux-gnu为例:

编译构建qtbase

本小节以在ubuntu系统下,交叉编译Arm64平台的Qt版本为目标。记录qtbase的编译构建步骤。

交叉编译器为:gcc-linara-6.3.1-2017.05-x86_64_aarch64-linux-gnu

(1)准备好交叉编译工具后,将交叉编译器的路径添加到ubuntu环境变量中。参见一文

(2)在源码目录下使用cd qtbase将终端切换到qtbase目录下。

(3)查看/qtbase/mkspecs/linux-aarch64-gnu-g++/qmake.conf文件内容。编译器一栏所填写的命令,需要与交叉编译器套件名称一样。小生的交叉编译器套件如下图所示:

(经对比,qmake.conf文件中交叉编译器名称与上图所示名称一样,故此处不用修改qmake.conf文件)

(4)在终端使用下列命令:

./configure \
-prefix 编译安装的目录路径  \
-xplatform linux-aarch64-gnu-g++ \
-no-opengl \
-opensource \
-confirm-license \
-release  \
-strip \
-shared \
-c++std c++11 \
--sqlite=qt \
-recheck-all

(注:可以将上述内容写成脚本,直接在终端下运行即可)

  • -prefix:该参数用于指定Qt编译完成后安装时的输出目录。

  • -xplatform:用于交叉编译时选择目标mkspec。(需与qtbase/mkspec目录下的目录名称一样)

其他参数含义可以使用./configure -help打印出帮助信息查看。

(5)使用make -j12编译构建qtbase。(-j12表示同时允许的任务数,计算机性能好,就指定12或更高。计算机性能弱就指定低数值或不指定-j参数)

注:根据编译构建环境的硬件配置,整个编译构建过程可能会需要几分钟甚至几十分钟。

(6)编译完成后,在终端使用make install命令将编译成功后的文件安装到-prefix参数指定的路径下。

安装完成后,会在-prefix参数指定的路径下自动创建几个目录,如下图所示:

  • bin:该目录下包含生成的Qt版本的二进制程序。例如:moc、qmake、rcc、uic等Qt构建工具。

  • doc:为对应模块的文档目录。

  • examples:该目录中存放的是与该模块相关的Qt演示demo(源码+生成的可执行体)。

  • include:该目录存放与该模块相关的包含头文件。

  • lib:该目录下存放的是与该模块相关的库文件。

  • plugins:该目录下存放插件目录,在对应插件目录下存放着对应的插件库文件。

在上述过程中,我们已经编译构建且安装好了qtbase,如果在开发中,还想增加其他的组件模块,我们可以直接到模块对应的目录路径下编译即可。例如,如果想编译构建qtcharts模块,可以按照如下步骤进行:

(1)切换到qtcharts目录路径下,打开终端。

(2)用在qtbase编译出的qmake工具来配置(这个qmake会自动延用qtbase交叉编译时的配置),qmake工具位于-prefix参数指定的路径下的bin目录中:

 编译安装的目录路径/bin/qamke

(3)使用make -j12编译构建。

(4)使用make install安装。

完整编译构建Qt源码

完整编译Qt源码指的是在Qt源码路径下进行编译,使用configure对Qt进行编译配置时指定需要编译的模块。

完整编译构建步骤如下:

(1)与上述编译qtbase一样,需要确保准备好了交叉编译器环境,且配置好具体目标平台下的qmake配置文件,然后在Qt源码目录下打开终端。

(2)使用下列命令配置Qt源码:

#! /bin/sh
./configure -prefix /home/Qt/qt-everywhere-src-5.12.9/arm-qt \
-opensource \
-confirm-license \
-release \
-strip \
-shared \
-xplatform linux-arm-gnueabi-g++ \
-optimized-qmake \
-c++std c++11 \
--rpath=no \
-pch \
-skip qt3d \
-skip qtactiveqt \
-skip qtandroidextras \
-skip qtcanvas3d \
-skip qtconnectivity \
-skip qtdatavis3d \
-skip qtdoc \
-skip qtgamepad \
-skip qtlocation \
-skip qtmacextras \
-skip qtnetworkauth \
-skip qtpurchasing \
-skip qtremoteobjects \
-skip qtscript \
-skip qtscxml \
-skip qtsensors \
-skip qtspeech \
-skip qtsvg \
-skip qttools \
-skip qttranslations \
-skip qtwayland \
-skip qtwebengine \
-skip qtwebview \
-skip qtwinextras \
-skip qtx11extras \
-skip qtxmlpatterns \
-make libs \
-make examples \
-nomake tools -nomake tests \
-gui \
-widgets \
-dbus-runtime \
--glib=no \
--iconv=no \
--pcre=qt \
--zlib=qt \
-no-openssl \
--freetype=qt \
--harfbuzz=qt \ -no-opengl \ -linuxfb \
--xcb=no \ -tslib \
--libpng=qt \
--libjpeg=qt \
--sqlite=qt \
-plugin-sql-sqlite \
-I/home/Qt/tslib-1.21/arm-tslib/include \
-L/home/Qt/tslib-1.21/arm-tslib/lib \
-recheck-all

上述的配置文本,可通过./configure -help查看对应的意思。

参考链接:https://doc.qt.io/qt-5/configure-options.html

上述配置跳过了几个Qt模块,且使用linuxfb作为显示平台插件,为ARM32编译Qt跨平台开发环境。

(3)在终端使用make -j12编译构建Qt源码。

(4)在终端使用make installl命令将编译成功后的文件安装到-prefix参数指定的路径下。


参考链接:

[1]http://wiki.friendlyelec.com/wiki/index.php/How_to_Build,_Install_and_Setting_Qt_Application/zh

[2] http://qt6.digitser.net/6.3/zh-CN/configure-linux-device.html

嵌入式Qt | 如何交叉编译Qt模块相关推荐

  1. Linux 启动qt 非法指令,交叉编译Qt 4.7时的“非法指令”

    我现在已经在这个问题上挣扎了一个多星期了,仍然无法找到解决方案-- 我正在尝试为ARM设备交叉编译Qt 4.7嵌入式开源版本.构建过程本身完成没有问题,但生成的二进制文件似乎包含处理器不理解的指令. ...

  2. 如何建立Qt Creator交叉编译嵌入式Linux

    如何建立Qt Creator交叉编译嵌入式Linux 介绍 Qt许可信息 Qt 5 安装Qt Creator 用于设备创建的Qt 构建和部署目标映像 构建用于开发的SDK 安装SDK 配置Qt Cre ...

  3. Qt 学习(三) —— Qt 模块

    1. Qt 模块简介 Qt由许多模块组成,分别支持不同领域的功能,主要分为 Essentials 和 Add-On. Qt Essential 是基本模块,它们可以在所有受支持的开发平台和经过测试的目 ...

  4. 嵌入式项目实战——基于QT的视频监控系统设计(二)

    嵌入式项目实战--基于QT的视频监控系统设计(二) 昨天我分享了关于QT的基本使用方法,掌握了这些基本的方法就可以设计一个简单的视频监控界面.下面我们开始分享完成这个嵌入式项目同样重要的知识点--UD ...

  5. 嵌入式项目实战——基于QT的视频监控系统设计(三)

    嵌入式项目实战--基于QT的视频监控系统设计(三) 进入到五一假期第三天,继续我们的项目.本来五一假期还是想好好休息一下的,因为最近学习的状态不太好,刷题都没有思路了,但是身边的同学太卷了,不过我还是 ...

  6. 嵌入式Linux下的Qt环境搭建

    嵌入式Linux下的Qt环境搭建 本文介绍如何在嵌入式Linux开发板上配置Qt运行环境,并进行Qt程序运行测试 一.tslib编译 要想Qt 支持触摸需要编译 tslib ,以生成触摸相关插件. t ...

  7. 嵌入式项目实战——基于QT的视频监控系统设计(四)

    嵌入式项目实战--基于QT的视频监控系统设计(四) 进入到五一假期的第四天,通过前三天的分享,相信你应该已经掌握了QT的基本使用.UDP网络编程.v4l2视频处理模块.多线程编程等基本的知识点.其实昨 ...

  8. [翻译] Qt QFtp功能无法被Qt 5 Network系列模块替代的说明

    Qt4下Qt提供了QFtp类以完成FTP相关的操作,但是Qt5不再提供QFtp类了,取而代之的是QNetworkAccessManager,QNetworkRequest和QNetworkReply等 ...

  9. Linux下的qt5.7Qftp类,[翻译] Qt QFtp功能无法被Qt 5 Network系列模块替代的说明

    Qt4下Qt提供了QFtp类以完成FTP相关的操作,但是Qt5不再提供QFtp类了,取而代之的是QNetworkAccessManager,QNetworkRequest和QNetworkReply等 ...

最新文章

  1. JDK源码研究Jstack,JMap,threaddump,dumpheap的原理
  2. 用Kettle的一套流程完成对整个数据库迁移 费元星
  3. Jupyter 快速入门——写python项目博客非常有用!!!
  4. 移动端、微信小程序页面布局参考
  5. 路由器有线优先吗_路由器要定时按这个键,很多人不懂,难怪网速又慢又卡!...
  6. springboot取yml中的值_@Value拜拜:更优雅的获取springboot yml中的值
  7. codeforces1553 F. Pairwise Modulo(数学)
  8. .net微信公众号开发——基础接口
  9. 超英文邮件50%!Flink 中文邮件列表必须有姓名
  10. [模板]匈牙利算法(二分图匹配)
  11. Flex和Flash之间相互调用
  12. 《计算机操作系统》(第四版)知识点总结
  13. Struts2面试题分析
  14. Redhat注册下载Redhat Enterprise Linux Download
  15. 在 Linux 中如何删除分区
  16. python 自动解析外文时间日期
  17. Dev,SIT,UAT, Staging, Prod,DR环境分别是意思?
  18. Python小例子,太走心~
  19. 安装监控的地方没有WiFi,没有无线网络,如何实现远程监控?
  20. 英文版-主我高举你的名-Lord I lift Your name on high-纯蓝歌词字幕

热门文章

  1. mysql命令表示最小_MySQL基本命令总结
  2. python发送邮件的几种常用方法
  3. 语义分割系列11-DAnet(pytorch实现)
  4. nrm切换npm淘宝镜像安装依赖
  5. Unhandled error during execution of render function
  6. B站服务器数据协议,B站直播间协议指南
  7. Idea的Marketplace打不开终极解决
  8. Word怎么撤销上一步操作
  9. vue3+cli4运行项目报错export ‘default‘ (imported as ‘VueRouter‘) was not found in ‘vue-router‘
  10. vue过滤器实现日期格式化