QT交叉编译

**摘要:**本文总结了在 Ubuntu(Linux x86_64)主机上交叉编译 Qt5.12.3 到 aarch64-linux-gnu(ARM64)平台的完整步骤,涵盖环境准备、工具链校验、源码下载、影子编译目录创建、mkspec 修改、configure 配置、编译安装与成果验证,并补充了 Windows 本地交叉编译的流程说明,帮助读者在 Linux 或 Windows 上构建可直接用于 ARM64 开发板的 Qt 套件。

Ubuntu(Linux x86_64)编译 Qt5.12.3 目标 aarch64-linux-gnu 完整步骤总结

用途:Linux 主机编译,产出:Linux 版 qmake/moc + ARM64 的 .so 库,可本地 Linux 编译 ARM 程序,也可给 Windows QtCreator 做 SSH 远程编译复用这套 Qt

1、环境准备

安装依赖包

bash 复制代码
sudo apt update
sudo apt install build-essential git perl bison flex python2
sudo apt install aarch64-linux-gnu-gcc aarch64-linux-gnu-g++

2、校验工具链

bash 复制代码
aarch64-linux-gnu-g++ -v
perl -v
flex --version
bison --version

3、源码准备

https://download.qt.io/new_archive/qt/5.12/5.12.3/single/

4、新建独立构建目录(影子编译),新建最终安装目录

创建一个空目录build-qt512-arm64

5、修改 mkspec(适配交叉编译器)

修改qt-everywhere-src-5.12.3/qtbase/mkspecs/linux-aarch64-gnu-g++/qmake.conf

确认编译器前缀:aarch64-linux-gnu-

bash 复制代码
#
# qmake configuration for building with aarch64-linux-gnu-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)
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)
~

~

~

~

~

~

~

~

~

~

"qt-everywhere-src-5.12.3/qtbase/mkspecs/linux-aarch64-gnu-g++/qmake.conf" 24L, 742B

6、configure 配置(示例最小编译,关闭冗余组件)

进入build-qt512-arm64目录,然后执行下面命令:

注意:这条是 qtbase/configure(仅编译 QtBase,不是全套 qt-everywhere) ,而且缺少启用 qtwebsockets,这就是为什么你套件没有 websockets 模块!

路径:../qt-everywhere-src-5.12.3/qtbase/configure → 只编译 qtbase 基础模块(core、gui、network 等),qtwebsockets 属于独立子模块,不在 qtbase 里面

bash 复制代码
# 进入构建目录
../qt-everywhere-src-5.12.3/qtbase/configure \
-release -opensource -confirm-license \
-prefix /home/linjl/Qt5.12.3-ARM64 \
-nomake tests -nomake examples \
-no-opengl -no-iconv -no-dbus -no-openssl \
-skip qtvirtualkeyboard -skip qtwebengine -skip qtscript \
-skip qtdeclarative -skip qtwayland -skip qt3d \
-platform linux-g++ -xplatform linux-aarch64-gnu-g++ \
QMAKE_CXXFLAGS+="-Wno-free-nonheap-object -Wno-deprecated-copy -Wno-error"

逐行参数解释

  1. ../qt-everywhere-src-5.12.3/qtbase/configure 调用 qtbase 子目录的配置脚本,仅配置 Qt 基础核心库(QtCore, QtNetwork, QtGui 等)

    ❗ 重点:qtwebsockets、qtserialport 这类模块不属于 qtbase,只用这个脚本编译不会构建 websockets

  2. -release 编译 Release 版本(不带调试符号,用于产品运行)

  3. -opensource -confirm-license 使用 Qt 开源协议,自动确认许可,不用手动交互

  4. -prefix /home/linjl/Qt5.12.3-ARM64 安装路径make install 后所有头文件、库、qmake 会安装到此目录

  5. -nomake tests -nomake examples 不编译自带测试程序、官方示例工程,节约编译时间与磁盘空间

  6. -no-opengl -no-iconv -no-dbus -no-openssl

    • -no-opengl:禁用 OpenGL 图形渲染(无 GUI / 不需要 GPU 渲染可关闭)
    • -no-iconv:禁用 iconv 编码库(解决之前 iconv 编译报错)
    • -no-dbus:禁用 DBus 进程间通信
    • -no-openssl:禁用 OpenSSL 加密(网络 SSL/TLS 会受限)
  7. -skip qtvirtualkeyboard -skip qtwebengine -skip qtscript -skip qtdeclarative -skip qtwayland -skip qt3d 跳过编译这些子模块,不参与构建,节省时间

    ⚠️ 这里没有 skip qtwebsockets,但问题根源:你调用的是 qtbase/configure,只会编译 qtbase,其它子模块默认不会编译

  8. -platform linux-g++ 宿主机(Ubuntu x86_64)编译工具:本机 gcc/g++,用于编译 qmake 等主机工具

  9. -xplatform linux-aarch64-gnu-g++ 目标平台 :交叉编译,产出 aarch64 (ARM64) Linux 程序,读取 mkspecs/linux-aarch64-gnu-g++ 配置交叉编译器

  10. QMAKE_CXXFLAGS+="-Wno-free-nonheap-object -Wno-deprecated-copy -Wno-error" 给交叉编译器 g++ 追加编译参数:

    • -Wno-free-nonheap-object:关闭 "释放非堆内存" 警告
    • -Wno-deprecated-copy:关闭废弃拷贝构造相关警告
    • -Wno-error警告不升级为错误(遇到兼容警告不会直接中断编译,适配高版本 GCC)

如果执行有类似下面的错误:

进入对应文件generator.cpp,在上面添加#include <limits>

然后删除build-qt512-arm64目录,重新创建一个,在执行。这边删除是为了清除旧的。

7、编译 + 安装

bash 复制代码
make -j$(nproc)
make install

8、成果验证

bash 复制代码
# 检查ARM库架构
file /home/linjl/Qt5.12.3-ARM64/lib/libQt5Core.so.5.12.3
# 输出:ELF 64-bit LSB shared object, ARM aarch64 → 编译成功

Qt5.12.3 aarch64 ARM64 交叉编译套件根目录 /home/linjl/Qt5.12.3-ARM64

lib/ 存放 aarch64 ARM64 Linux 平台的 Qt 动态库 libQt5Core.solibQt5Gui.so ...

9、使用

创建一个build目录,然后进入build目录执行。make编译出可执行文件后,使用linuxdeployqt等工具打包后,直接拷贝到目标服务器即可运行,目标服务器无需下载qt等任何东西。

bash 复制代码
/home/linjl/Qt5.12.3-ARM64/bin/qmake xxx.pro
make

Windows 本地编译 Qt5.12.3(aarch64-linux-gnu 交叉版)完整步骤

目标:在 Windows 主机上编译出一套可直接给 Windows 版 Qt Creator 本地使用的 ARM64 交叉 Qt 套件

下载 Qt 源码

F:\lin-dev\work\Qt-cross-compile\qt-everywhere-src-5.12.3\qtbase\mkspecs

Qt 编译平台配置目录(mkspec = make specification)

F:\lin-dev\work\Qt-cross-compile\qt-everywhere-src-5.12.3\qtbase\mkspecs\linux-aarch64-gnu-g++

这个是 Qt5.12.3 官方自带的 AArch64(64 位 ARM,ARM64,RK3588、树莓派 4 64 位等 ARM Linux)交叉编译 mkspec 模板 内部包含两张文件:

1、qmake.conf ✅【核心配置文件】:定义编译器、编译 / 链接参数、标志

bash 复制代码
#
# qmake configuration for building with aarch64-linux-gnu-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)
【核心】指定 AArch64 Linux 交叉工具链程序
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++
归档、拷贝、符号、strip 工具
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
加载 Qt 内置配置(末尾必须保留)
load(qt_config)

安装交叉编译器

用于编译Qt源码,生成可以在arm平台上面运行的库。

gcc-arm-11.2-2022.02-mingw-w64-i686-aarch64-none-linux-gnu.zip

  • gcc-arm-11.2-2022.02GCC 11.2 版本,Arm 官方 2022.02 发布套件
  • mingw-w64-i686主机运行环境:Windows(32 位 MinGW,可在 64 位 Win10/11 兼容运行)
  • aarch64-none-linux-gnu目标架构:AArch64(ARM64) + 目标系统:ARM64 Linux(glibc 标准库)

下载路径: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/downloads

解压一下,可以改个比较简短的名字,然后添加到环境变量中:F:\lin-dev\work\Qt-cross-compile\Qt5.12.12-ARMv8\bin

安装关联软件

ActiveState Perl

Windows 原生没有预装 Perl,编译完整 Qt 源码(qt-everywhere-src)必须安装 Strawberry Perl

Qt 源码编译流程中大量 .pl Perl 脚本:syncqt.pl、代码自动生成、ICU、WebKit、部分通讯模块(MQTT/OPC UA)都依赖 Perl 解释器运行,因为我们要编译qt源码,所以需要这个

Strawberry Perl for Windows - Releases

双击strawberry-perl-5.36.3.1-64bit.msi进行安装

验证安装结果:

安装python3

编译 Qt 源码

修改qmake.conf配置文件

GCC 10/11 之后,很多 GCC 警告默认升级成 -Werror(警告 = 编译错误) Qt 5.12.3 是很老的版本(官方最高适配 GCC 8),源码写法不符合新版 GCC 的严格规范,于是直接编译中断。 mingw32-make 本身只是构建工具,报错不是 mingw32-make 引起的,是 aarch64-none-linux-gnu-g++(你的交叉编译器)抛出的编译错误

mingw32-make 的作用:读取 configure 生成的 Makefile,调用你的 aarch64-none-linux-gnu-g++ 交叉编译器编译源码; mingw32-make ≠ 交叉编译器,它只是调度工具。

所以需要修改一下防止mingw32-make 编译的时候报错**。**

F:\lin-dev\work\Qt-cross-compile\qt-everywhere-src-5.12.3\qtbase\mkspecs\linux-aarch64-gnu-g++\qmake.conf

bash 复制代码
#
# qmake configuration for building with aarch64-none-linux-gnu-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)
modifications to g++.conf
QMAKE_CC                = aarch64-none-linux-gnu-gcc
QMAKE_CXX               = aarch64-none-linux-gnu-g++
QMAKE_LINK              = aarch64-none-linux-gnu-g++
QMAKE_LINK_SHLIB        = aarch64-none-linux-gnu-g++
modifications to linux.conf
QMAKE_AR                = aarch64-none-linux-gnu-ar cqs
QMAKE_OBJCOPY           = aarch64-none-linux-gnu-objcopy
QMAKE_NM                = aarch64-none-linux-gnu-nm -P
QMAKE_STRIP             = aarch64-none-linux-gnu-strip
load(qt_config)
QMAKE_CXXFLAGS += -fpermissive -Wno-class-memaccess -Wno-error=permissive
QMAKE_CFLAGS += -fpermissive

QMAKE_CXXFLAGS

C++ 编译器参数(g++ /aarch64-none-linux-gnu-g++) 用于编译 .cpp .hpp C++ 源码。

  • -fpermissive:放宽 C++ 语法,把部分非法转换降为警告(解决 const char** 报错)
  • -Wno-class-memaccess:关闭 memcpy 拷贝类对象的检查告警

QMAKE_CFLAGS

C 编译器参数(gcc /aarch64-none-linux-gnu-gcc) 只用于编译纯 .c C 语言源码,不作用于 cpp 文件

+= = 追加参数(保留原有编译器配置,新增参数)

运行configure生成构建规则

因为我们需要再arm平台运行我们的程序,所以我们需要编译Qt的源码好让我们写的程序可以运行在arm上面,因为我们依赖于Qt的源码,所以要编译Qt源码成可以在arm上面运行的库。

进入下载的源码目录qt-everywhere-src-5.12.3

Windows(MSYS2/CMD)下,对 qt-everywhere-src-5.12.3 整套 Qt 源码进行【交叉编译配置】

目标:编译产出 ARM64 (aarch64/ARMv8) Linux 平台版本的 Qt5.12.3 库 ,后续用这套 ARM 版 Qt 库编译你的 .pro Qt 程序,放到 ARM64 Linux 开发板(RK3588 等)运行。

1、创建目录

2、进入目录打开Powershell

bash 复制代码
../qt-everywhere-src-5.12.3/configure `
-release `
-opensource `
-confirm-license `
-prefix F:\lin-dev\work\Qt-cross-compile\Qt5.12.3-arm64 `
-nomake tests `
-nomake examples `
-no-opengl `
-skip qtvirtualkeyboard `
-linuxfb `
-platform win32-g++ `
-xplatform linux-aarch64-gnu-g++
  1. .\configure.bat Windows 专用配置脚本(Linux 下是 ./configure),用于检测编译环境、编译器、依赖库,生成构建规则。

⚠️ 注意:你的源码版本是 5.12.3 ,但 prefix 路径写了 5.12.12,版本号不一致,属于笔误,建议统一。

  1. -release 编译 Release 发行版本 (不带调试符号,体积更小、运行更快;与之对应 -debug 调试版),嵌入式板子一般用 release。

  2. -opensource 声明使用 Qt 开源协议(GPL/LGPL),搭配 -confirm-license 可以自动同意协议(你这条命令缺少这个参数,运行时会交互式确认许可证)。

  3. -prefix D:\Qt\Qt5.12.12-ARMv8 安装输出目录 :编译完成后执行 make install,所有 ARM 版 Qt 库、头文件、qmake、工具都会安装到这个文件夹。

注意:虽然是 Windows 路径,但里面产出的是 ARM Linux 平台的二进制库(.so),不能在 Windows 运行,只能拷贝到 ARM 开发板

  1. -nomake tests / -nomake examples 不编译 Qt 自带的测试程序、官方示例工程,节省编译时间、减少最终库体积(嵌入式交叉编译标配参数)。

  2. -no-opengl 禁用 OpenGL 支持。

风险:如果你的 Qt 程序用到 QOpenGLWidget、3D 绘图,后续编译自己项目会报错;仅纯 2D Widget、linuxfb 无 GPU 界面才适合关闭。

  1. -skip qtvirtualkeyboard 跳过整个 qtvirtualkeyboard 模块,不去编译这个软键盘组件,减少编译耗时。

  2. -platform win32-g++ 主机平台(构建机环境) :当前你运行 configure 的系统是 Windows,使用 Windows 上 MinGW 编译器,用来编译 Qt 构建过程中需要的主机端工具(moc、uic、rcc 等)

原理:交叉编译需要一套运行在 Windows 本地的工具链处理代码生成,再用交叉编译器编译 ARM 平台库。

  1. -xplatform aarch64-linux-gnu-g++ ✅【核心交叉参数】 目标平台 :指定使用 qtbase/mkspecs/aarch64-linux-gnu-g++ 里的交叉编译规则(也就是你之前修改的 qmake.conf),告诉 Qt:最终库要编译给 aarch64 (ARM64) Linux 系统。

执行完后的结果:

执行mingw32-make进行编译

读取 configure 生成的 Makefile,调用qmake.conf中设置的编译器: aarch64-none-linux-gnu-g++ 交叉编译器编译源码;

执行mingw32-make install输出结果

bash 复制代码
F:\lin-dev\work\Qt-cross-compile\qt-everywhere-src-5.12.3\configure.bat ^
-platform win32-g++ ^
-xplatform linux-aarch64-gnu-g++ ^
-prefix F:\lin-dev\work\Qt-cross-compile\Qt5.12.3-arm64-win ^
-release ^
-opensource ^
-confirm-license ^
-nomake tests ^
-nomake examples ^
-no-opengl ^
-no-openssl ^
-no-cups ^
-no-dbus ^
-no-sqlite ^
-no-iconv ^
-qt-libjpeg ^
-qt-libpng ^
-qt-zlib ^
-skip qtwebengine ^
-skip qtdeclarative ^
-skip qtmultimedia ^
-skip qtwayland ^
-skip qt3d ^
qtwebsockets ^
QMAKE_CXXFLAGS+="-Wno-free-nonheap-object -Wno-deprecated-copy -Wno-error -fpermissive"

相关推荐
2601_9669496515 分钟前
如何判断盘中最新价相对昨日收盘涨跌幅,并实时触发止盈止损条件单:QuantDash Python 实战
开发语言·python·量化策略·量化·quantdash
下辈子不要当码农21 分钟前
Day7-Linux软件编程(进程与线程(3))
java·开发语言
Quz24 分钟前
QML 焦点导航:Tab 顺序与方向键移动
qt
程与留32 分钟前
11_常用控件速查(上):QPushButton、QLabel、QLineEdit、QComboBox
c++·qt
Quz36 分钟前
QML 按键事件之方向控制
qt
CarIise37 分钟前
JavaScript进阶与轮播图实现 课堂笔记
开发语言·javascript·笔记
mayaairi43 分钟前
JS DOM节点操作完全指南:增删改查与性能优化
开发语言·javascript·性能优化
Demon--hx44 分钟前
多态实现原理
开发语言·c++
wanglei2007081 小时前
消息队列的协作模式
开发语言·python