第一部分:QT的起源、设计哲学与初始版本源码树形分析

1. QT开发库设计的由来与初衷

  • 时代背景: 1990年代初期,Unix/X11下的GUI开发非常原始和碎片化。程序员主要直接使用Xlib API,这是一个极其底层、复杂且在不同Unix变体上行为不一致的C语言库。虽然存在Motif等工具包,但它们价格昂贵、外观陈旧且同样难以使用。

  • 创始人与契机: 1994年,挪威的Haavard NordEirik Chambe-Eng(Qt的两位“爸爸”)正在为一个跨平台的仿真软件项目寻找合适的GUI工具包。他们受尽了X11编程的折磨,并对市场上的解决方案感到失望。

  • 设计初衷: 他们的核心目标是创建一个 “真正跨平台” 的C++ GUI框架。这个框架需要满足:

    1. “一次编写,到处编译”: 源代码无需修改,即可在Windows、Unix/X11、Mac等系统上编译和运行。

    2. 面向对象: 使用C++的特性,通过直观的类层次结构来封装复杂的原生GUI API,提高开发效率和代码可维护性。

    3. 组件化与可扩展性: 提供丰富的预制UI组件(按钮、文本框等),并且允许用户通过继承轻松创建自定义组件。

    4. 良好的性能: 不能因为抽象而带来过大的性能开销,需要接近原生应用的响应速度。

    5. 统一的API: 无论底层操作系统如何,都提供一套完全相同、语义一致的API。

为什么设计QT? 简而言之,是为了解决当时C++ GUI编程的痛苦,提供一个生产力更高、体验更一致的工业级解决方案。

2. QT初始版本(以Qt 1.0为例)源码树形分析与软件设计

Qt 1.x的源码树相对现代Qt要简单得多,但其核心架构思想已经确立。假设一个类似1.0版本的简化源码树结构:

qt-1.0/
├── src/
│   ├── kernel/           # 核心非GUI类
│   │   ├── qobject.h/.cpp    # 元对象系统核心,信号与槽的基石
│   │   ├── qapplication.h/.cpp # 应用程序对象,事件循环核心
│   │   ├── qevent.h/.cpp      # 事件类定义
│   │   └── qpoint.h, qrect.h... # 几何基础类
│   ├── widgets/          # GUI控件类
│   │   ├── qwidget.h/.cpp     # 所有窗口部件的基类
│   │   ├── qbutton.h/.cpp     # 按钮基类
│   │   ├── qpushbutton.h/.cpp # 具体按钮实现
│   │   ├── qlabel.h/.cpp      # 标签
│   │   └── ... 
│   ├── dialog/           # 对话框类
│   │   ├── qdialog.h/.cpp
│   │   ├── qfiledialog.h/.cpp
│   │   └── ...
│   ├── painter/          # 绘图引擎
│   │   ├── qpainter.h/.cpp    # 绘图工具
│   │   ├── qpaintdevice.h/.cpp # 绘图设备抽象
│   │   └── qcolor.h, qpen.h... # 绘图资源
│   └── moc/              # 元对象编译器 (moc)
│       └── moc.cpp       # 一个独立的C++程序,不是库的一部分
├── include/              # 对外头文件
├── lib/                  # 编译生成的库文件
└── tools/
    └── designer/         # Qt Designer 初始版本?(可能在更晚版本加入)

软件设计与性能分析:

  1. qobject.h/.cpp - 元对象系统(Meta-Object System):

    • 设计模式: 大量使用了工厂方法模式(通过Q_OBJECT宏和moc生成类信息)、观察者模式的变体(信号与槽)命令模式(封装操作,如事件)。

    • 软件设计: 这是Qt的灵魂。它通过引入moc(元对象编译器)这个代码生成器,在C++语言之外,为类添加了运行时类型信息(RTTI)动态方法调用的能力。这解决了C++原生RTTI能力弱的问题。

    • 性能分析: 信号与槽的连接是类型安全的,其调用开销略高于直接函数调用,但远低于动态语言的反射。它通过一个内部的连接对象数组进行查找和调用,是空间换时间的典型设计。相比于回调函数,它更安全,但引入了微小的间接调用开销。

  2. qapplication.h/.cpp - 应用程序与事件循环:

    • 设计模式: 单例模式(一个进程一个QApplication实例)、事件循环模式模板方法模式QApplication::exec()定义了算法骨架,具体事件处理由虚函数如event()处理)。

    • 软件设计: 封装了不同操作系统下的消息泵。它将来自操作系统(如X11的XEvent, Windows的MSG)的原始事件,翻译成Qt的QEvent对象,并通过QObject::event()函数派发给相应的目标控件。这是一个抽象层(Adapter Pattern) 和** facade模式**的体现,向上层应用开发者隐藏了平台的复杂性。

    • 性能分析: 事件循环本身是高效的,它通常在一个while循环中阻塞等待系统事件。主要的性能瓶颈在于事件处理函数(如paintEvent)中的业务逻辑效率。Qt内部对事件进行了合并优化,例如重绘事件。

  3. qwidget.h/.cpp - 窗口部件基类:

    • 设计模式: 组合模式(父控件管理子控件,形成树形结构)、策略模式(布局管理)、装饰器模式(如样式表)。

    • 软件设计: QWidget是所有UI元素的基类。它持有一个QWidget* parent指针,天然构成了一棵对象树。当父对象析构时,会自动析构所有子对象,这是一种责任链模式的应用,简化了内存管理。它内部还包含一个指向底层平台窗口的句柄(如X11的Window)。

    • 性能分析: 窗口部件的树形结构决定了事件传递和绘制的顺序。一个深层次的控件树可能会增加事件传递的路径。Qt的绘图是增量且局部的,通常只重绘update()repaint()请求的区域(脏区域),这是GUI性能的关键优化。

  4. qpainter.h/.cpp - 绘图引擎:

    • 设计模式: 策略模式(不同的绘图设备,如屏幕、位图、打印机,使用相同的QPainter接口)、状态模式(保存/恢复画笔、画刷等状态)。

    • 软件设计: QPainter是一个统一抽象的2D绘图API。它不关心底层是使用X11的Xlib、Windows的GDI,还是macOS的Quartz2D。这是桥接模式的完美体现,将抽象(绘图命令)与实现(平台特定的绘图操作)分离。

    • 性能分析: 在X11上,早期Qt可能直接使用Xlib,后来转向XRender等更现代的扩展以改善性能和字体渲染。在内存中绘图(QPixmap)通常很快,而直接向屏幕绘图则受限于图形驱动和硬件。QPainter进行了大量优化,如路径简化、坐标转换的矩阵运算等。


第二部分:QT手动裁剪与最小化物理空间

1. 场景:为何会产生“裁剪”这个概念?

裁剪概念的产生源于嵌入式系统和资源受限设备的兴起。

  • 核心场景:

    1. 嵌入式Linux设备: 如工业控制器、车载信息娱乐系统、智能家电、物联网网关等。这些设备的共同特点是:

      • 存储空间有限: Flash/ROM可能只有几十MB甚至几MB。

      • 内存有限: RAM可能只有128MB或更少。

      • CPU性能较弱: 通常是ARM/MIPS等低功耗处理器。

    2. 启动时间要求: 设备要求快速启动,较小的库加载更快。

    3. 安全与维护: 更少的代码意味着更小的攻击面和更少的潜在bug。

在这些场景下,一个完整的Qt库(可能超过100MB)是完全不可接受的。因此,必须有一种方法,只保留应用程序真正用到的功能,剔除所有无关代码,从而将最终的库文件(.so)和应用程序体积降到最低。

2. 使QT .so库体积最小的裁剪方法

要达到最小的物理空间,需要一套组合拳,从编译配置到代码编写多管齐下。

  1. 编译期配置:configure脚本 这是最核心、最有效的裁剪手段。在编译Qt源码时,运行./configure并传入大量参数来禁用不需要的模块和功能。

    • 禁用整个模块:

      -no-sql-mysql -no-sql-psql -no-qt3d -no-multimedia -no-positioning -no-webengine ...
    • 优化编译选项:

      -release -optimize-size -no-pch -no-feature-<featurename> ...

      -optimize-size让编译器以空间优化为首要目标。-no-pch禁用预编译头文件,虽然会减慢编译速度,但可能减少中间文件复杂度。-no-feature-<featurename>可以禁用更细粒度的功能,所有可用的feature可以通过-list-features查看。

    • 静态链接 vs 动态链接:

      • 静态链接: 使用-static。编译器会将你用到的、且未被禁用的Qt代码直接打包进最终的可执行文件。这通常会产生一个比动态链接方式下“应用程序+所有.so”总和更小的体积,因为链接器可以只提取你用到的目标文件中的代码段,并进行更激进的死代码消除。这是获得最小化空间的终极手段。

      • 动态链接: 生成多个.so文件。优点是共享,多个应用可以共用一份Qt库。但为了最小化单个.so,你需要将Qt本身也编译成多个更小的、模块化的.so。

  2. 链接期优化:链接器死代码消除 这是与静态链接配合使用的关键技术。

    • 原理: 当静态链接时,链接器可以看到所有的目标文件(.o)。它会从你的main函数开始,分析整个调用图,只将那些最终被调用到的函数和数据链接到最终的可执行文件中。未被调用的函数(例如,你从未使用过QFileDialog,那么相关的代码就会被当作“死代码”剔除)。

    • 要求: 要使此技术效果最佳,要求代码在编译时使用-ffunction-sections -fdata-sections选项,链接时使用-Wl,--gc-sections。这样每个函数和数据都会在独立的“section”中,便于链接器精确剔除。

  3. 源代码级优化:

    • 避免使用宏大的头文件: 例如,使用<QWidget>会引入大量声明。如果只需要字符串,就只包含<QString>

    • 谨慎使用模板和内联函数: 它们会“爆炸”式地增加代码体积。

    • 使用Qt的轻量级类: 例如,在不需要隐式共享的场景下,考虑使用QStringView替代QString

  4. 使用工具进行分析:

    • nmobjdump: 分析二进制文件中的符号,查看哪些函数被链接进去了。

    • bloaty: 一个专门用于分析二进制文件各个部分大小的工具,可以精确到哪个源文件、哪个函数占了多少空间。

总结最小化流程:

  1. 分析你的应用,明确需要哪些Qt模块和功能。

  2. 使用极简的configure命令,禁用所有不需要的模块和功能。

  3. 选择静态链接,并开启编译器和链接器的尺寸优化选项。

  4. 编译你的应用和Qt库。

  5. 使用工具分析生成的可执行文件,持续迭代,剔除不必要的代码引用。

3.至今最后一版免费开源版本QT 5.15.2

Qt 5.15.x 的最后一个开源版本(包括 5.15.2, 5.15.13 等)的授权许可是 LGPLv3 和 GPL。只要选择遵守 LGPLv3 条款,就可以免费用于商业闭源项目。

将遵循以下步骤,并在ARM32和ARM64架构上进行对比:

  1. 环境准备与源码获取

  2. 配置参数的深度解析与最小化配置

  3. 编译与安装

  4. ARM32与ARM64的树形分析与对比

  5. 最终优化与验证


3.1. 环境准备与源码获取

首先,你需要一个针对目标架构(ARM32/ARM64)的交叉编译工具链。例如,对于ARM64,可能是 aarch64-linux-gnu-g++,对于ARM32,可能是 arm-linux-gnueabihf-g++

获取Qt源码: 推荐使用安装程序或Git获取指定版本的源码,例如Qt 5.15 LTS或Qt 6.2+。

wget https://download.qt.io/official_releases/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.tar.xz
tar -xf qt-everywhere-src-5.15.2.tar.xz
cd qt-everywhere-src-5.15.2

3.2. 配置参数的深度解析与最小化配置

这是裁剪的核心。创建一个配置脚本来确保可重复性。

创建配置脚本:configure_minimal.sh
#!/bin/bash
​
# 定义变量
BUILD_DIR="build-minimal"
INSTALL_DIR="/opt/qt-minimal-5.15.2-arm64" # 根据架构修改,如 ...-arm32
QT_SRC_DIR="$(pwd)"
​
# 设置交叉编译工具链 (示例为ARM64,请根据你的工具链修改)
export TOOLCHAIN_DIR="/path/to/your/toolchain"
export PATH=$TOOLCHAIN_DIR/bin:$PATH
export CROSS_COMPILE="aarch64-linux-gnu-"
export SYSROOT="/path/to/your/target/sysroot" # 目标板的根文件系统
​
# 对于ARM32,工具链可能类似:
# export CROSS_COMPILE="arm-linux-gnueabihf-"
​
# 创建构建和安装目录
mkdir -p $BUILD_DIR
cd $BUILD_DIR
​
# 核心配置命令
$QT_SRC_DIR/configure \
    -prefix $INSTALL_DIR \
    -platform linux-g++ \
    -xplatform linux-aarch64-gnu-g++ \
    # 对于ARM32,使用对应的设备描述符,例如:
    # -xplatform linux-arm-gnueabi-g++ \
    -sysroot $SYSROOT \
    \
    ### 编译模式和优化 ###
    -release \                # 发布模式,去除调试符号和断言
    -optimize-size \          # 优化目标为尺寸而非速度
    -no-pch \                 # 禁用预编译头文件,减少复杂性和依赖
    -ltcg \                   # 链接时代码生成,更激进的死代码消除(Qt5部分版本/Qt6支持)
    -reduce-relocations \     # 减少重定位,优化动态库大小
    \
    ### 静态链接配置 (实现最小体积的终极手段) ###
    -static \                 # 生成静态库
    -static-runtime \         # 静态链接C++运行时库
    \
    ### 核心功能裁剪:禁用几乎所有非核心GUI模块 ###
    -no-opengl \
    -no-dbus \
    -no-icu \
    -no-glib \
    -no-gif \
    -no-ico \
    -no-libjpeg \
    -no-libpng \
    -no-compile-examples \
    -no-sql-db2 -no-sql-ibase -no-sql-mysql -no-sql-oci -no-sql-odbc -no-sql-psql -no-sql-sqlite \
    -no-qt3d \
    -no-activeqt \
    -no-multimedia \
    -no-network \
    -no-positioning \
    -no-printsupport \        # 注意:如果你的“初始显示控件”需要打印,则保留
    -no-sensors \
    -no-serialport \
    -no-sql \
    -no-testlib \
    -no-webkit -no-webengine -no-widgets \ # 注意:-no-widgets 会移除所有GUI控件,这里*需要*控件,所以不能加!
    -no-xml \
    -no-xcb \                 # 禁用X11,使用LinuxFB直接操作帧缓冲区
    \
    ### 细粒度功能裁剪 (-no-feature-*) ###
    # 这些是获得极致体积的关键
    -no-feature-accessibility \
    -no-feature-animation \
    -no-feature-clipboard \
    -no-feature-colordialog \
    -no-feature-commandlinkbutton \
    -no-feature-concurrent \
    -no-feature-dial \
    -no-feature-filedialog \
    -no-feature-fontdialog \
    -no-feature-freetype \
    -no-feature-ftp \
    -no-feature-gestures \
    -no-feature-graphicsview \
    -no-feature-http \
    -no-feature-imageformat-bmp \
    -no-feature-imageformat-jpeg \
    -no-feature-imageformat-png \
    -no-feature-imageformat-ppm \
    -no-feature-imageformat-xbm \
    -no-feature-imageformat-xpm \
    -no-feature-im \
    -no-feature-inputdialog \
    -no-feature-itemviews \
    -no-feature-keysequenceedit \
    -no-feature-lcdnumber \
    -no-feature-mdiarea \
    -no-feature-messagebox \
    -no-feature-paintdebug \
    -no-feature-progressdialog \
    -no-feature-proxymodel \
    -no-feature-sessionmanager \
    -no-feature-socks5 \
    -no-feature-sqlmodel \
    -no-feature-statemachine \
    -no-feature-syntaxhighlighter \
    -no-feature-textbrowser \
    -no-feature-textmarkdownwriter \
    -no-feature-textodfwriter \
    -no-feature-toolbar \
    -no-feature-toolbutton \
    -no-feature-tooltip \
    -no-feature-undo \
    -no-feature-wizard \
    -no-feature-css \
    \
    ### 强制启用最小核心GUI和LinuxFB ###
    -gui \
    -widgets \                # 必须启用,因为依赖初始控件(QPushButton, QLabel等)
    -qt-zlib \                # 使用内置的最小zlib
    -qt-freetype \            # 使用内置的freetype(如果必须渲染文字)
    -linuxfb \                # 使用Linux帧缓冲区,最轻量的显示后端
    \
    -nomake examples -nomake tests -nomake tools # 不编译示例和工具
​
echo "Configuration complete. Now run 'make -j$(nproc)' and 'make install'."

关键点解释:

  • -static-static-runtime: 这是实现最小体积的最关键决策。静态链接允许链接器进行全局死代码消除,只将应用程序实际调用的代码打包进去。

  • -no-feature-*: 这些参数比 -no-<module> 更细致。例如,即使你保留了 -widgets 模块,也可以通过 -no-feature-filedialog 来移除 QFileDialog 相关的所有代码。通过 ./configure -list-features 可以查看所有可裁剪的功能。

  • -linuxfb: 对于无X11/Wayland的嵌入式环境,这是最直接的显示方式,依赖最少,体积最小。

  • -optimize-size -no-pch -ltcg: 这一套组合拳从编译器、链接器层面全方位优化尺寸。


3.3. 编译与安装

给脚本执行权限并运行。

chmod +x configure_minimal.sh
./configure_minimal.sh

$BUILD_DIR 中开始编译:

# 使用所有CPU核心编译,加快速度
make -j$(nproc)
​
# 安装到配置时指定的 $INSTALL_DIR
make install

编译完成后,在 $INSTALL_DIR 目录下就是你裁剪后的Qt库。


3.4. ARM32与ARM64的树形分析与对比

分别对ARM32和ARM64执行上述流程,然后在安装目录下使用 treedu 命令进行分析。

树形结构分析 (tree 命令)

ARM64 最小化安装目录结构 (示例):

/opt/qt-minimal-5.15.2-arm64/
├── bin/
│   ├── moc          # 元对象编译器 (宿主机的二进制文件,体积固定)
│   ├── qmake        # 构建工具 (宿主机的二进制文件,体积固定)
│   └── ...
├── lib/
│   ├── libQt5Core.a         # 核心库,静态库
│   ├── libQt5Gui.a          # GUI库,静态库
│   ├── libQt5Widgets.a      # 控件库,静态库
│   └── ...
└── ...

ARM32 最小化安装目录结构: 结构完全一致,只是库文件是针对ARM32架构编译的。

关键观察:

  • 由于使用静态编译,最终的输出是 .a 文件,而不是 .so。目标是最终应用程序的体积,而不是动态库的体积。

  • 工具(如 moc, qmake)是运行在宿主机上的,它们的体积与目标架构无关,是固定的。

体积对比分析 (du -shls -lh 命令)

假设编译一个只显示一个按钮的极简程序 main.cpp

#include <QApplication>
#include <QPushButton>
​
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QPushButton button("Minimal Qt");
    button.show();
    return a.exec();
}

使用安装目录下的 qmakemake 来编译它。

编译应用程序 (在宿主机上,使用刚编译的Qt):

export QT_INSTALL_DIR=/opt/qt-minimal-5.15.2-arm64
$QT_INSTALL_DIR/bin/qmake -project
$QT_INSTALL_DIR/bin/qmake
make -j$(nproc)

使用 aarch64-linux-gnu-strip 对生成的最终可执行文件进行剥离,去除所有符号表和调试信息。

然后,分析最终的可执行文件:

架构 最终可执行文件大小 (Strip后) 主要组成部分 (使用 bloaty 分析)
ARM64 ~ 4-6 MB - [.text] 段: 主要的程序代码 (来自你的app和Qt) - [.rodata] 段: 只读数据 (字符串常量等) - [.data] / [.bss]: 已初始化/未初始化数据
ARM32 ~ 3-5 MB 同上

对比分析与结论:

  1. 体积差异原因

    • 指令集: ARM64是64位指令集,通常指令本身占用的空间会比ARM32的32位指令稍大。

    • 寄存器数量: ARM64有更多的通用寄存器,可能会减少对栈的访问,但指令编码格式可能不同。

    • 对齐要求: 64位系统对内存地址对齐的要求可能更严格,可能引入少量填充。

    • 结果: 在进行了极致裁剪后,ARM64的可执行文件通常比ARM32大 10%~30%。这个差距已经通过静态链接和死代码消除被大大缩小。

  2. 树形结构对比结论

    • 结构一致性: 两个架构的安装目录树形结构完全一致。这证明了Qt构建系统的一致性。

    • 内容本质差异: 唯一的区别在于 lib/ 目录下的静态库文件内容,它们包含了不同CPU架构的机器码。从文件系统树来看,没有差异。


3.5. 最终优化与验证
  1. 链接器优化: 确保在编译你的应用程序时,在 .pro 文件或Makefile中传递了链接器优化标志。

    QMAKE_LFLAGS += -Wl,--gc-sections
    QMAKE_CFLAGS += -ffunction-sections -fdata-sections
    QMAKE_CXXFLAGS += -ffunction-sections -fdata-sections

    这允许链接器移除未被使用的函数和数据段。

  2. 使用分析工具

    • bloaty: 强烈推荐。它可以告诉你可执行文件中哪个符号、哪个源文件占用了最多空间。

      bloaty your_minimal_app -n 20 --domain=compileunits
    • aarch64-linux-gnu-nm / arm-linux-gnueabihf-nm: 查看二进制文件中的符号。

      aarch64-linux-gnu-nm --size-sort your_minimal_app | tail -20

      这可以列出最大的符号。

  3. 验证功能: 将编译好的最小可执行文件放到目标板上运行,确保按钮能正常显示和响应。使用 topps 查看其内存占用,也会非常小。

通过这套完整的流程,你可以为ARM32和ARM64嵌入式平台生成一个仅包含最基本显示控件的、体积最小的Qt应用程序。核心在于静态链接激进的模块和功能裁剪以及链接器级别的死代码消除

在 Qt 4.0 时代,ARM64 架构还没有正式支持,可以通过交叉编译的方式让 Qt 4.0 在 ARM64 上运行。以下是详细的配置方案:

4.Qt 4.0 ARM64 强制移植配置

#!/bin/bash
​
# Qt 4.0 ARM64 强制移植配置脚本
# 注意:这需要自定义工具链和补丁
​
# 定义变量
BUILD_DIR="build-qt4-arm64-forced"
INSTALL_DIR="/opt/qt4-forced-arm64"
QT_SRC_DIR="$(pwd)"
​
# 设置 ARM64 交叉编译工具链
export TOOLCHAIN_DIR="/path/to/aarch64-toolchain"
export PATH=$TOOLCHAIN_DIR/bin:$PATH
export CROSS_COMPILE="aarch64-linux-gnu-"
export SYSROOT="/path/to/arm64-sysroot"
​
# 设置编译器和工具
export CC="${CROSS_COMPILE}gcc"
export CXX="${CROSS_COMPILE}g++"
export AR="${CROSS_COMPILE}ar"
export STRIP="${CROSS_COMPILE}strip"
export RANLIB="${CROSS_COMPILE}ranlib"
​
# 创建构建目录
mkdir -p $BUILD_DIR
cd $BUILD_DIR
​
# 应用必要的补丁(如果需要)
echo "Applying ARM64 compatibility patches..."
# patch -p1 < ../qt4-arm64-atomic.patch
​
# Qt 4.0 ARM64 强制配置
$QT_SRC_DIR/configure \
    ### 基础架构配置 ###
    -prefix $INSTALL_DIR \
    -platform linux-g++ \
    -xplatform linux-g++ \    # 使用通用的 linux-g++,手动覆盖工具链
    -sysroot $SYSROOT \
    \
    ### 工具链手动覆盖 ###
    -cc $CC \
    -cxx $CXX \
    -ar $AR \
    -strip $STRIP \
    \
    ### ARM64 特定优化 ###
    -release \
    -no-debug \
    -optimize-size \
    -no-exceptions \
    -no-rtti \
    \
    ### 静态链接配置 ###
    -static \
    -qt3support \
    \
    ### 架构特性调整 ###
    -no-mmx \
    -no-3dnow \
    -no-sse \
    -no-sse2 \
    -no-neon \                # ARM64 可能需要处理 NEON 支持
    \
    ### 核心模块裁剪 ###
    -no-opengl \
    -no-webkit \
    -no-script \
    -no-scripttools \
    -no-multimedia \
    -no-audio-backend \
    -no-phonon \
    -no-svg \
    -no-xmlpatterns \
    -no-dbus \
    -no-openssl \
    -no-glib \
    -no-icu \
    -no-pch \
    \
    ### 数据库支持裁剪 ###
    -no-sql-ibase \
    -no-sql-mysql \
    -no-sql-odbc \
    -no-sql-psql \
    -no-sql-sqlite \
    \
    ### 图像格式裁剪 ###
    -no-gif \
    -no-libmng \
    -no-libjpeg \
    -no-libpng \
    -no-tiff \
    \
    ### 显示和输入配置 ###
    -qt-gfx-linuxfb \
    -no-gfx-vnc \
    -no-gfx-qvfb \
    -qt-mouse-tslib \         # 触摸屏支持
    -qt-kbd-tty \
    \
    ### 强制启用核心功能 ###
    -qt-gui \
    -qt-zlib \
    -no-freetype \
    \
    ### 构建控制 ###
    -nomake examples \
    -nomake demos \
    -nomake tools \
    \
    ### 兼容性选项 ###
    -no-accessibility \
    -no-stl \
    -no-largefile \
    -DQT_ARCH_ARMV8 \         # 强制定义 ARMv8 架构
    -DQT_NO_ATOMIC_ARM64 \    # 如果原子操作有问题则禁用
​
echo "Qt 4.0 ARM64 forced configuration complete."
必要的补丁文件

由于 Qt 4.0 原生不支持 ARM64,可能需要创建补丁文件:

4.1. ARM64 原子操作补丁 qt4-arm64-atomic.patch
--- src/corelib/arch/qatomic_arm.h
+++ src/corelib/arch/qatomic_arm.h
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL3 included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_ARM64_H
+#define QATOMIC_ARM64_H
+
+#include <QtCore/qglobal.h>
+
+#ifdef Q_OS_LINUX
+# include <asm/unistd.h>
+#endif
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+#if defined(Q_CC_GNU)
+
+/* ARM64 asm implementation */
+
+template <int size> struct QAtomicOpsBySize;
+
+template <> struct QAtomicOpsBySize<4> {
+    static inline Q_ALWAYS_INLINE bool isTestAndSetNative() { return true; }
+    static inline Q_ALWAYS_INLINE bool isTestAndSetWaitFree() { return true; }
+    
+    static inline Q_ALWAYS_INLINE bool testAndSetRelaxed(int &_q_value, int expectedValue, int newValue)
+    {
+        int result;
+        __asm__ __volatile__(
+            "0: ldaxr %w0, [%1]\n"
+            "   cmp %w0, %w2\n"
+            "   b.ne 1f\n"
+            "   stlxr %w0, %w3, [%1]\n"
+            "   cbnz %w0, 0b\n"
+            "1:"
+            : "=&r" (result)
+            : "r" (&_q_value), "r" (expectedValue), "r" (newValue)
+            : "memory", "cc");
+        return result == 0;
+    }
+    
+    // 添加其他必要的原子操作...
+};
+
+#endif // Q_CC_GNU
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif // QATOMIC_ARM64_H
4.2. 配置脚本增强版

创建更完整的配置脚本 configure_qt4_arm64_advanced.sh

#!/bin/bash
​
# Qt 4.0 ARM64 高级强制移植配置
​
# 定义变量
BUILD_DIR="build-qt4-arm64-advanced"
INSTALL_DIR="/opt/qt4-arm64-advanced"
QT_SRC_DIR="$(pwd)"
​
# ARM64 工具链配置
export TOOLCHAIN_DIR="/usr/aarch64-linux-gnu"
export CROSS_COMPILE="aarch64-linux-gnu-"
export SYSROOT="${TOOLCHAIN_DIR}"
​
export CC="${CROSS_COMPILE}gcc"
export CXX="${CROSS_COMPILE}g++"
export AR="${CROSS_COMPILE}ar"
export STRIP="${CROSS_COMPILE}strip"
export RANLIB="${CROSS_COMPILE}ranlib"
export LD="${CROSS_COMPILE}ld"
export OBJCOPY="${CROSS_COMPILE}objcopy"
​
# 设置编译标志
export CFLAGS="-march=armv8-a -mtune=cortex-a53 -O2 -fPIC"
export CXXFLAGS="-march=armv8-a -mtune=cortex-a53 -O2 -fPIC"
export LDFLAGS="-Wl,-O1 -Wl,--as-needed"
​
# 创建构建目录
mkdir -p $BUILD_DIR
cd $BUILD_DIR
​
echo "=== Qt 4.0 ARM64 Forced Porting ==="
echo "Toolchain: $CC"
echo "Sysroot: $SYSROOT"
echo "Build dir: $BUILD_DIR"
echo "Install dir: $INSTALL_DIR"
​
# 创建自定义的 mkspec(关键步骤)
mkdir -p mkspecs/linux-arm64-g++
cat > mkspecs/linux-arm64-g++/qmake.conf << 'EOF'
MAKEFILE_GENERATOR = UNIX
TARGET_PLATFORM = unix
TEMPLATE = app
CONFIG += qt warn_on release incremental link_prl
QT += core gui
​
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++
​
QMAKE_AR = aarch64-linux-gnu-ar cqs
QMAKE_OBJCOPY = aarch64-linux-gnu-objcopy
QMAKE_STRIP = aarch64-linux-gnu-strip
​
QMAKE_CFLAGS = -march=armv8-a -mtune=cortex-a53 -O2 -fPIC
QMAKE_CXXFLAGS = -march=armv8-a -mtune=cortex-a53 -O2 -fPIC
QMAKE_LFLAGS = -Wl,-O1
​
load(qt_config)
EOF
​
# 配置命令
$QT_SRC_DIR/configure \
    -verbose \
    -prefix $INSTALL_DIR \
    -platform linux-g++ \
    -xplatform linux-arm64-g++ \
    -sysroot $SYSROOT \
    \
    -release \
    -optimize-size \
    -no-debug \
    -no-exceptions \
    -no-rtti \
    \
    -static \
    -qt3support \
    \
    # 架构特定调整
    -no-mmx -no-3dnow -no-sse -no-sse2 \
    \
    # 模块裁剪
    -no-opengl \
    -no-webkit \
    -no-script \
    -no-scripttools \
    -no-multimedia \
    -no-svg \
    -no-dbus \
    -no-openssl \
    -no-glib \
    -no-icu \
    \
    # 显示配置
    -qt-gfx-linuxfb \
    -no-gfx-vnc \
    -no-gfx-qvfb \
    \
    # 输入配置
    -qt-mouse-tslib \
    -qt-kbd-tty \
    \
    # 核心功能
    -qt-gui \
    -qt-zlib \
    -no-freetype \
    -no-libjpeg \
    -no-libpng \
    \
    # 构建控制
    -nomake examples \
    -nomake demos \
    -nomake tools \
    \
    # 兼容性
    -no-accessibility \
    -no-stl \
    -no-largefile \
    -D__ARM_ARCH_8__ \
    -D__aarch64__
​
# 检查配置结果
if [ $? -eq 0 ]; then
    echo "=== Configuration successful ==="
    echo "Run: make -j$(nproc) && make install"
else
    echo "=== Configuration failed ==="
    echo "Check the config.log for details"
fi
构建和调试步骤
4.2.1. 准备工具链
# 在 Ubuntu/Debian 上安装 ARM64 工具链
sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
4.2.2. 应用补丁和配置
# 应用必要的补丁
cd qt-everywhere-opensource-src-4.0.0
patch -p1 < ../qt4-arm64-atomic.patch
​
# 运行配置脚本
chmod +x configure_qt4_arm64_advanced.sh
./configure_qt4_arm64_advanced.sh
4.2.3. 处理常见编译错误

错误1:原子操作不支持

# 在 src/corelib/arch/ 创建 qatomic_arm64.h
# 使用上面提供的补丁内容

错误2:汇编语法错误

# 修改 src/corelib/arch/qatomic_arm.cpp
# 将 ARM32 汇编替换为 ARM64 汇编

错误3:类型大小不匹配

# 在配置时添加定义
-DQT_POINTER_SIZE=8 \
-D__LP64__=1 \
4.2.4. 测试应用程序
// 简单的测试程序 test_arm64.cpp
#include <QApplication>
#include <QLabel>
​
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QLabel label("Qt 4.0 running on ARM64!");
    label.show();
    return app.exec();
}

编译测试程序:

export QT_INSTALL_DIR=/opt/qt4-arm64-advanced
$QT_INSTALL_DIR/bin/qmake -project
$QT_INSTALL_DIR/bin/qmake
make
​
# 检查生成的二进制文件
file test_arm64
# 应该显示:test_arm64: ELF 64-bit LSB executable, ARM aarch64, version 1...
注意事项
  1. 原子操作:Qt 4.0 的原子操作需要为 ARM64 重新实现

  2. 字节序:ARM64 是小端架构,与 Qt 4.0 的假设一致

  3. 对齐要求:ARM64 有严格的对齐要求

  4. 系统调用:可能需要调整系统调用号

  5. 浮点运算:ARM64 使用不同的浮点寄存器组

这种方法虽然复杂,但可以让 Qt 4.0 在 ARM64 架构上运行,适合特定的嵌入式或遗留系统迁移场景。

5.Qt 4.x 版本关键变更分析

版本 引入模块 移除/废弃模块 功能变更
4.0 (2005) - QtNetwork - QtSql - QtXml - QtOpenGL - QtSvg - QtTest - Qt 3.x 的兼容类开始废弃 - 旧的绘画系统 - 完全模块化架构 - 新的绘画系统 Arthur - 新的构建系统 qmake
4.1 (2005) - QtWebKit (技术预览版) - QtUiTools - WebKit 集成 - 插件系统改进
4.2 (2006) - QtDBus - QtHelp - D-Bus 支持 - 帮助系统
4.3 (2007) - QtScript - ECMAScript 支持 - 性能优化
4.4 (2008) - QtWebKit (正式版) - QtMultimedia - Phonon 模块 - 多媒体框架 - 并发编程支持
4.5 (2009) - QtScriptTools - WebKit 性能大幅提升 - 新的动画框架
4.6 (2009) - QtDeclarative (技术预览) - QtMobility - QML 引入 - 移动设备支持
4.7 (2010) - QtDeclarative (正式版) - QML 成熟 - 新的图形视图框架
4.8 (2011) - 部分 Qt 3.x 兼容类完全移除 - 最后 LTS 版本 - 性能优化

Qt 4.0 最小裁剪配置脚本

#!/bin/bash
​
# Qt 4.0 最小化裁剪配置脚本
# 注意:Qt 4.x 时代的配置选项与现代 Qt 5/6 有很大差异
​
# 定义变量
BUILD_DIR="build-qt4-minimal"
INSTALL_DIR="/opt/qt-minimal-4.0-arm"
QT_SRC_DIR="$(pwd)"
​
# 设置交叉编译工具链 (ARM32 示例)
export TOOLCHAIN_DIR="/path/to/your/arm-toolchain"
export PATH=$TOOLCHAIN_DIR/bin:$PATH
export CROSS_COMPILE="arm-linux-gnueabi-"
export SYSROOT="/path/to/your/arm-sysroot"
​
# 创建构建目录
mkdir -p $BUILD_DIR
cd $BUILD_DIR
​
# Qt 4.0 核心配置命令
$QT_SRC_DIR/configure \
    ### 基础配置 ###
    -prefix $INSTALL_DIR \
    -platform linux-g++ \
    -xplatform linux-arm-g++ \
    -embedded arm \
    -sysroot $SYSROOT \
    \
    ### 编译模式和优化 ###
    -release \                # 发布模式
    -no-debug \               # 禁用调试
    -no-exceptions \          # 禁用异常(减少体积)
    -no-rtti \                # 禁用 RTTI(减少体积)
    -optimize-size \          # 尺寸优化
    \
    ### 静态链接配置 ###
    -static \                 # 静态链接
    -qt3support \             # 注意:Qt4 默认包含 Qt3 支持,需要显式禁用
    \
    ### 核心模块裁剪 ###
    -no-opengl \              # 禁用 OpenGL
    -no-webkit \              # 禁用 WebKit(4.0 还没有,但保留兼容性)
    -no-script \              # 禁用脚本
    -no-scripttools \         # 禁用脚本工具
    -no-multimedia \          # 禁用多媒体
    -no-audio-backend \       # 禁用音频后端
    -no-phonon \              # 禁用 Phonon
    -no-phonon-backend \      # 禁用 Phonon 后端
    -no-svg \                 # 禁用 SVG
    -no-xmlpatterns \         # 禁用 XML 模式
    -no-dbus \                # 禁用 D-Bus
    -no-nas-sound \           # 禁用 NAS 声音
    -no-openssl \             # 禁用 SSL
    -no-glib \                # 禁用 Glib
    -no-gstreamer \           # 禁用 GStreamer
    -no-icu \                 # 禁用 ICU
    -no-pch \                 # 禁用预编译头文件
    \
    ### 数据库支持裁剪 ###
    -no-sql-ibase \
    -no-sql-mysql \
    -no-sql-odbc \
    -no-sql-psql \
    -no-sql-sqlite \
    -no-sql-sqlite2 \
    \
    ### 图像格式裁剪 ###
    -no-gif \
    -no-libmng \
    -no-libjpeg \
    -no-libpng \
    -no-tiff \
    -no-mmx \
    -no-3dnow \
    -no-sse \
    -no-sse2 \
    \
    ### 字体和样式裁剪 ###
    -no-freetype \
    -no-fontconfig \
    -no-sm \                   # 禁用会话管理
    -no-xshape \
    -no-xsync \
    -no-xinerama \
    -no-xcursor \
    -no-xfixes \
    -no-xrandr \
    -no-xrender \
    -no-mitshm \
    -no-xinput \
    -no-nis \
    -no-cups \
    -no-iconv \
    \
    ### 显示后端配置 ###
    -qt-gfx-linuxfb \         # Linux 帧缓冲区
    -no-gfx-vnc \
    -no-gfx-transformed \
    -no-gfx-qvfb \
    -no-gfx-multiscreen \
    \
    ### 鼠标和输入设备 ###
    -qt-mouse-pc \
    -no-mouse-linuxtp \
    -no-mouse-tslib \
    -no-mouse-qvfb \
    -no-mouse-pc \
    \
    ### 键盘输入 ###
    -qt-kbd-tty \             # TTY 键盘
    -no-kbd-qvfb \
    -no-kbd-sl5000 \
    \
    ### 强制启用最小核心功能 ###
    -qt-gui \                 # 启用 GUI 模块
    -qt-sql-sqlite \          # 使用内置 SQLite(如果需要)
    -qt-zlib \                # 使用内置 zlib
    \
    ### 构建控制 ###
    -nomake examples \        # 不编译示例
    -nomake demos \           # 不编译演示
    -nomake docs \            # 不编译文档
    -nomake tools \           # 不编译工具
    \
    ### Qt 4 特定的配置 ###
    -depths 8,16,32 \         # 指定颜色深度
    -no-largefile \           # 禁用大文件支持
    -no-accessibility \       # 禁用无障碍支持
    -no-stl \                 # 禁用 STL(激进裁剪)
    -no-openssl \             # 禁用 OpenSSL
    -no-nis \                 # 禁用 NIS
    -no-cups \                # 禁用 CUPS 打印支持
    -no-iconv \               # 禁用 iconv
    -no-pcre \                # 禁用 PCRE
​
echo "Qt 4.0 minimal configuration complete."
echo "Now run: make -j$(nproc) && make install"

Qt 4.x 配置与现代 Qt 的主要差异

5.1. 配置系统差异
# Qt 4.x 特有的选项
-embedded arm                # 嵌入式目标指定
-depths 8,16,32             # 颜色深度控制
-qt-gfx-linuxfb             # 显示后端配置方式不同
-qt-mouse-pc                # 输入设备配置
​
# 与现代 Qt 不同的选项
-no-qt3support              # Qt4 需要显式禁用 Qt3 兼容
-no-stl                     # 可禁用 STL(激进做法)
-no-exceptions              # 可禁用异常
-no-rtti                    # 可禁用 RTTI
5.2. 模块化程度差异
  • Qt 4.0 模块化刚刚开始,很多功能还在核心库中

  • 功能裁剪主要通过 -no-<feature> 而非 -no-feature-<featurename>

  • 没有细粒度的特性系统,裁剪相对粗放

5.3. 编译优化差异
# Qt 4.x 可用的激进优化
-no-exceptions              # 现代 Qt 通常不建议使用
-no-rtti                    # 可能影响某些功能
-no-stl                     # 现代 Qt 已不可用
5.4. 目标平台配置
# Qt 4.x 的嵌入式配置方式
-embedded arm
-xplatform linux-arm-g++
-qt-gfx-linuxfb
-qt-mouse-tslib             # 触摸屏支持
构建和执行
  1. 准备环境

    chmod +x configure_qt4_minimal.sh
    ./configure_qt4_minimal.sh
  2. 编译安装

    cd build-qt4-minimal
    make -j$(nproc)
    make install
  3. 验证结果

    # 检查安装目录
    ls -la $INSTALL_DIR/lib
    # 应该只看到核心的静态库:libQtCore.a, libQtGui.a 等

这个 Qt 4.0 的最小化配置体现了早期 Qt 嵌入式开发的典型做法,与现代 Qt 相比,配置选项更加直接但功能粒度较粗。

6.从 Qt 4.x 到当前 Qt 6.x 时代,configure 指令功能模块的主要变化历程:

时期 / 版本 引入的主要功能 / 模块 (代表性) 移除 / 废弃的功能 / 模块 (代表性) configure 系统的核心变化与影响
Qt 4.x (2005) 模块化-qt-gui (QtGui), -qt-network (QtNetwork), -qt-sql (QtSql), -qt-xml (QtXml), -qt-webkit (QtWebKit, 4.4), -qt-script (QtScript), -qt-multimedia (QtMultimedia, 4.4), -qt-declarative (QtDeclarative, QML基础, 4.7) • 图形-qt-opengl (QtOpenGL) • 图像格式-qt-svg (QtSvg) • 开始废弃一些更陈旧的、Qt 3.x 时代的兼容接口和类。 奠定模块化基础configure 开始支持通过 -no-<module> 参数排除整个模块,如 -no-webkit 。 • 嵌入式裁剪:引入 -qconfig 选项,允许通过自定义头文件(如 qconfig-small.h)精细裁剪特性(Feature),这是 Qt Lite 概念的早期实践 。
Qt 5.x (2012) 模块拆分与新增-qt-widgets (从 QtGui 拆分), -qt-quick (QtQuick), -qt-3d (Qt3D), -qt-serialport (QtSerialPort, 5.1), -qt-webengine (QtWebEngine, 基于 Chromium, 5.6 替代 QtWebKit) • 移动与嵌入式-qt-bluetooth (QtBluetooth, 5.2), -qt-positioning (QtPositioning, 5.2) -qt-webkit:在 5.6 版本被标记为废弃,并由 QtWebEngine 替代 。 • -script:QtScript 等相关模块开始被废弃,QML 和 JavaScript 成为更主流的脚本方案。 Qt Lite 项目:在 Qt 5.8 引入 -feature-<name>-no-feature-<name> 参数,支持在模块内进行更细粒度的功能裁剪(如 -no-feature-clipboard)。可通过 ./configure -list-features 查看列表 。 • 构建部分:支持 -nomake examples-nomake tests 来跳过示例和测试的编译 。
Qt 6.x (2020) 现代化模块-qt-quick3d (QtQuick3D), -qt-shadertools (QtShaderTools), -qt-languageserver (QtLanguageServer) • 兼容性模块-qt-5compat (Qt5Compat) • 网络与通信-qt-httpserver (QtHttpServer, 6.3), -qt-grpc (QtGrpc, 6.3) 大量废弃模块QtScript 被完全移除。在 6.0 初期,QtWebEngine 也暂时缺席(6.2 回归)。 • 构建系统革命qmake 不再是 Qt 自身的构建工具。 构建系统切换configure 成为 CMake 的封装器 。所有配置最终由 CMake 处理。 • 新的配置选项:引入如 -link-time-optimization (LTO)-gc-binaries 等用于优化和缩减体积的选项 。 • 模块管理:使用 -skip-submodules 来排除或包含子模块 。
Qt 5.x 之前版本的配置特点

由于资料有限,对于 Qt 1.x 到 3.x 的时代,只能勾勒出其配置系统的大致轮廓:

  • Qt 3.x 及更早版本:那时的 Qt 库相对单一和集中。configure 脚本的选项远没有现在丰富,主要侧重于基础性的配置,例如:

    • 指定安装路径(-prefix)。

    • 选择编译类型(-release-debug)。

    • 启用或禁用有限的组件,比如可能包括对 OpenGL 的支持。

    • 调整平台特定的设置。

    • 其核心思想是 "全部构建"或"少量排除",缺乏后来版本中精细的模块化和裁剪能力。

最新版 Qt 6 配置指令精要总结

进入 Qt 6 时代,配置指令全面转向以 CMake 为底层。以下是当前进行定制化构建,尤其是为了裁剪体积时,最核心和剩下常用的指令分类:

  1. 构建模式与优化

    • -static:生成静态链接库,是减少依赖和最终发布体积的关键。

    • -release:使用发布模式编译,移除调试符号。

    • -optimize-size:优化目标为尺寸而非速度。

    • -link-time-optimization (LTO):链接时优化,有助于进一步减小体积和提升性能。

    • -gc-binaries:与编译器标志(如 -ffunction-sections -fdata-sections)和链接器标志(如 -Wl,--gc-sections)结合,移除未使用的代码。

  2. 模块管理

    • -submodules <module1,module2,...>仅编译指定的子模块及其依赖。

    • -skip <module>:从构建中排除指定的子模块。

    • -nomake examples-nomake tests:不编译示例和测试,节省时间。

  3. 功能级裁剪

    • -no-feature-<featurename>:禁用 Qt 模块内部的特定功能,这是实现精细裁剪的利器。使用 ./configure -list-features 查看所有可用特性。

  4. 第三方库

    • -system-<lib>-qt-<lib>:选择使用系统上的第三方库还是 Qt 捆绑的库,例如 -system-zlib

  5. 平台与工具链

    • -prefix <dir>:指定安装目录。

    • -sysroot <dir>:指定目标系统的根目录,对交叉编译至关重要。

    • 通过 -DCMAKE_TOOLCHAIN_FILE=path 传递工具链文件给 CMake。

Qt 的 configure 系统演进史,是一部从 "大而全" 到 "精细可控" 的进化史:

  • Qt 4.x 开启了模块化,并针对嵌入式引入了初步的特性裁剪-qconfig)。

  • Qt 5.x 深化了模块化,并通过 Qt Lite 项目带来了革命性的功能级裁剪-no-feature-xxx)。

  • Qt 6.x 则完成了构建系统的现代化,全面转向 CMake,并将所有配置统一于此。

7.Qt模块与功能变更完整追踪方法

7.1. 获取历史数据的权威方法
# 获取完整的Qt历史仓库(巨大,约4GB+)
git clone https://code.qt.io/qt/qt5.git
cd qt5
​
# 查看模块引入的历史记录
git log --oneline --grep="Add.*module" --all
git log --oneline --grep="Remove.*module" --all
​
# 分析特定模块的历史
git log --oneline -- src/qt3d/
git log --oneline -- src/qtwebengine/
7.2. Qt主要版本模块演进树形分析
Qt 4.x 时代 (2005-2011)

基础模块结构:

qt4/
├── core/           # QtCore - 1995年最初引入
├── gui/            # QtGui - 1995年最初引入  
├── network/        # QtNetwork - Qt 4.0 (2005)
├── sql/            # QtSql - Qt 4.0 (2005)
├── xml/            # QtXml - Qt 4.0 (2005)
├── opengl/         # QtOpenGL - Qt 4.0 (2005)
├── svg/            # QtSvg - Qt 4.0 (2005)
├── script/         # QtScript - Qt 4.3 (2007)
├── webkit/         # QtWebKit - Qt 4.4 (2008) ✨新增
├── multimedia/     # QtMultimedia - Qt 4.4 (2008) ✨新增
├── declarative/    # QtDeclarative (QML) - Qt 4.7 (2010) ✨新增
└── scripttools/    # QtScriptTools - Qt 4.5 (2009)

关键patch示例:

  • commit 123abc (2008): Add QtWebKit module - Web rendering engine based on WebKit

  • commit 456def (2010): Introduce QtDeclarative module for QML support

Qt 5.x 时代 (2012-2020)

模块化重构 - Qt 5.0 (2012):

qt5/
├── base/
│   ├── core/               # QtCore
│   ├── gui/                # QtGui (拆分出窗口系统无关部分)
│   ├── widgets/            # QtWidgets ✨新增 (从QtGui拆分)
│   ├── network/            # QtNetwork
│   └── ...
├── addons/
│   ├── qt3d/               # Qt3D - Qt 5.0 ✨新增
│   ├── qtquick1/           # QtQuick1 (兼容Qt4 QML)
│   ├── qtserialport/       # QtSerialPort - Qt 5.1 ✨新增
│   └── ...
├── graphics/
│   ├── qtdeclarative/      # QtQml, QtQuick ✨重构
│   └── ...
└── ...

Qt 5.x 版本关键变更:

版本 引入模块 移除/废弃模块 功能变更
5.0 (2012) - QtWidgets - QtQml - QtQuick - Qt3D - QtLocation - QtSensors - QtWebKit (标记为废弃) - QtScript (开始废弃) - 图形架构重构 - QML成为一等公民
5.1 (2013) - QtSerialPort - QtXmlPatterns - Android/iOS支持
5.2 (2013) - QtBluetooth - QtNfc - QtPositioning - WinRT支持
5.4 (2015) - QtWinExtras - QtMacExtras - QtX11Extras - 高性能Shader效果
5.6 (2016) - QtWebEngine ✨新增 (替代WebKit) - QtWebKit (正式移除) - 长期支持版本
5.7 (2016) - QtGamepad - Qt3DAnimation - Qt3DExtras - 3D功能增强
5.9 (2017) - QtRemoteObjects - QtSpeech - LTS版本 - 进程间通信增强
5.12 (2018) - QtShaderTools - QtWaylandCompositor - QtScriptTools (废弃) - 现代图形管线
5.15 (2020) - QtLottie - QtQuick3D - 最后5.x LTS
Qt 6.x 时代 (2020-现在)

架构重大重构 - Qt 6.0 (2020):

qt6/
├── qtbase/                 # 核心基础模块重构
├── qt5compat/              # Qt5兼容模块 ✨新增
├── qtshadertools/          # 着色器工具 (提升为核心)
├── qtquick3d/              # 3D渲染 (从附加模块提升)
├── qtmultimedia/           # 多媒体重构
├── qtpositioning/          # 定位服务
├── qtnetwork/              # 网络栈现代化
├── qtlanguageserver/       # 语言服务器协议 ✨新增
└── ...

Qt 6.x 版本关键变更:

版本 引入模块 移除/废弃模块 功能变更
6.0 (2020) - qt5compat - qtlanguageserver - qtquick3dphysics - QtScript (完全移除) - QtWebEngine (暂不包含) - QtMultimediaWidgets (移除) - CMake构建系统 - C++17要求 - 新图形架构
6.2 (2021) - QtWebEngine ✨回归 - QtPdf - QtQuick3D - WebEngine回归 - 3D功能增强
6.3 (2022) - QtHttpServer - QtGrpc - QtQuick3DParticleEffects - 微服务支持 - gRPC集成
6.4 (2022) - QtPositioningQuick - QtSpacialAudio - 部分Qt5兼容类 - 定位服务增强 - 空间音频
6.5 (2023) - QtGraphs ✨新增 - QtDeviceUtilities - 图表库引入 - 设备工具
6.6 (2023) - QtMultimediaWidgets ✨回归 - 多媒体部件回归 - 性能优化
6.7 (2024) - QtApplicationManager - QtWebView - 应用管理 - Web视图改进
7.3. 详细功能级变更记录
配置选项变更分析

Qt 5.15 → Qt 6.0 重大变更:

# Qt 5.15 中存在的配置选项,在 Qt 6.0 中移除或变更
- -no-opengl                  # 在 Qt6 中被 -no-opengl 和 -no-vulkan 替代
- -qt-host-path               # 被 CMake 变量替代
- -no-eglfs                   # 平台插件系统重构
- -system-proxies             # 网络栈重构影响
- -qpa                        # QPA架构变更
​
# Qt 6.0 新增配置选项
- -feature-vulkan             # Vulkan支持
- -cmake-generator            # CMake生成器选项
- -qt-namespace               # 命名空间控制
模块级功能裁剪历史

Web引擎模块的演进:

2008: QtWebKit 引入 (Qt 4.4)
2012: QtWebKit 继续在 Qt5.0 中使用
2015: QtWebEngine 引入 (Qt 5.6),基于Chromium
2016: QtWebKit 标记为废弃 (Qt 5.6)
2018: QtWebKit 从官方发布中移除 (Qt 5.12+)
2020: QtWebEngine 暂不包含在 Qt6.0
2021: QtWebEngine 回归 (Qt 6.2)

3D图形模块发展:

2012: Qt3D 引入 (Qt 5.0) - 基础3D支持
2016: Qt3D 扩展 (Qt 5.7) - 动画和额外组件
2020: QtQuick3D 引入 (Qt 5.15) - 声明式3D
2021: QtQuick3D 成为主要3D方案 (Qt 6.2)
2023: QtQuick3D 物理引擎 (Qt 6.5)
7.4. 自动化分析脚本
#!/bin/bash
# analyze_qt_history.sh
​
QT_SRC_DIR="$1"
MODULE="$2"
​
echo "=== Analyzing history of $MODULE ==="
​
# 查看模块引入时间
echo "1. Module introduction:"
git -C "$QT_SRC_DIR" log --reverse --oneline --grep="add.*$MODULE" --all | head -5
​
# 查看主要变更
echo -e "\n2. Major changes:"
git -C "$QT_SRC_DIR" log --oneline --since="2010-01-01" -- "$MODULE" | head -10
​
# 查看配置选项变更
echo -e "\n3. Configure changes:"
git -C "$QT_SRC_DIR" log --oneline --grep="configure.*$MODULE" --all | head -5
​
# 使用示例: ./analyze_qt_history.sh /path/to/qt5 qtwebengine
7.5. 树形结构对比分析工具
#!/usr/bin/env python3
# qt_module_analyzer.py
​
import os
import subprocess
from datetime import datetime
​
def analyze_qt_version(qt_path, version):
    """分析特定Qt版本的模块结构"""
    modules = {}
    
    # 分析src目录
    src_path = os.path.join(qt_path, 'src')
    if os.path.exists(src_path):
        for module in os.listdir(src_path):
            module_path = os.path.join(src_path, module)
            if os.path.isdir(module_path):
                # 计算模块大小
                size = get_directory_size(module_path)
                modules[module] = {
                    'size': size,
                    'type': 'core'
                }
    
    return modules
​
def generate_tree_comparison(qt_versions):
    """生成版本间树形对比"""
    print("Qt Module Evolution Tree")
    print("=" * 50)
    
    for version, modules in qt_versions.items():
        print(f"\n{version}:")
        for module, info in modules.items():
            status = "🆕" if is_new_module(module, version) else "  "
            print(f"  {status} {module:20} {info['size']:>10} MB")
​
if __name__ == "__main__":
    # 这里需要实际路径
    qt_versions = {
        'Qt 4.8': analyze_qt_version('/path/to/qt4.8', '4.8'),
        'Qt 5.15': analyze_qt_version('/path/to/qt5.15', '5.15'),
        'Qt 6.5': analyze_qt_version('/path/to/qt6.5', '6.5'),
    }
    generate_tree_comparison(qt_versions)
7.6. 关键结论
  1. 模块化趋势:从Qt4的相对集中到Qt5的模块化,再到Qt6的现代化重构

  2. Web技术演进:WebKit → WebEngine 的转换反映了Web技术的快速发展

  3. 3D图形发展:从基础的OpenGL包装到完整的声明式3D解决方案

  4. 构建系统变革:qmake → CMake 的转变影响了整个生态

  5. 移动和嵌入式:不断增加对移动平台和嵌入式设备的优化支持


第三部分:QT源码与授权

  • QT源码是开源包嘛? 是的,Qt源码是开源的。 它采用双重许可模式:

    • GPL/LGPLv3: 对于开源项目,你可以遵循这些协议免费使用Qt。

    • 商业许可: 如果你希望开发闭源的商业软件,或者需要Qt公司的官方支持,则需要购买商业许可证。

  • 从那个版本开始收费的? Qt从诞生之初就具有商业属性。 它的商业模式一直是“双重许可”。所以不存在“从哪个版本开始收费”的说法,而是一直同时提供免费(开源)和收费(商业)两种获取方式。不过,其具体的开源协议(GPL/LGPL)版本和条款在不同大版本间有所变化。例如,Qt 4.x早期版本是LGPL v2.1,从Qt 4.5开始同时提供LGPL v2.1和v3选项。Qt 5和Qt 6则主要基于GPLv3、LGPLv3和商业协议。

Logo

openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。

更多推荐