ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Qt5.14.2 aarch64静态交叉编译全链路实践指南

Qt5.14.2 aarch64静态交叉编译全链路实践指南 1. 为什么静态交叉编译 Qt5.14.2 到 aarch64 不是“配个环境就能跑”而是必须重走一遍构建链路你在网上搜“Qt5.14.2 交叉编译 aarch64”十有八九会看到一堆零散的命令片段./configure -xplatform linux-aarch64-gnu-g ...、make -j8、make install。看起来三步搞定但实际动手时90%的人卡在第一步——连 configure 都跑不起来报错qmake not found、cannot find -lGL、missing OpenSSL headers或者更隐蔽的编译成功了但生成的可执行文件在目标板上一运行就Segmentation fault (core dumped)。这不是你操作错了而是绝大多数教程默认你已经站在一个“预设好的平台”上比如它假设你用的是 Ubuntu 20.04 官方源里的gcc-aarch64-linux-gnu工具链且该工具链已自带完整的 C 标准库libstdc.so、线程支持libpthread、甚至 OpenGL ES 的 stub 库它还假设你的宿主机x86_64上早已装好了所有 Qt 构建依赖比如libxcb-xinerama0-dev、libxkbcommon-x11-0-dev、libfontconfig1-dev……而这些在 Ubuntu 22.04 或 24.04 上包名可能已变或根本不再提供 32 位兼容库更关键的是它完全没提“静态链接”这个前提带来的连锁反应——当你指定-static时Qt 不再只是链接动态库.so它要将整个 QtCore、QtGui、QtWidgets 的代码连同其所有底层依赖zlib、freetype、harfbuzz、icu、openssl全部打碎、重定位、合并进你的最终二进制里。这意味着你不仅得让 Qt 自己编译通过还得确保它所依赖的每一个第三方库都以静态方式被编译、安装、并被 Qt 的 configure 脚本准确识别到。我去年在给一款国产 ARM64 工业网关做 HMI 界面时就踩过这个坑。当时用的是飞腾 D2000 平台厂商只提供了最小化 rootfs里面连/lib/ld-linux-aarch64.so.1都是阉割版。我们按网上教程交叉编译出的 Qt 动态库拷过去后ldd一看依赖 17 个.so而目标系统只提供了其中 3 个。临时方案是把所有.so打包塞进去结果发现版本冲突宿主机编译的libicuuc.so.66和目标板上运行时加载的libicuuc.so.60符号不兼容程序启动直接 abort。最后倒逼我们回到原点从头构建一套全静态、无外部运行时依赖的 Qt 工具链。这个过程耗时 11 天核心不是技术多难而是每一步都像在迷雾中排雷你永远不知道下一个报错是来自工具链本身的缺陷还是 Qt 源码里某个硬编码路径抑或是 configure 脚本对 aarch64 架构的静态链接支持存在历史遗留 bug。所以这本手册的出发点很朴素不教你“怎么快速跑通一个 demo”而是带你亲手把 Qt5.14.2 这座大厦的地基、钢筋、水泥、水电管线一根一根、一寸一寸地浇筑出来。它不回避那些藏在configure日志第 327 行的 warning不跳过make install后发现libQt5Core.a里居然缺失qglobal.o的诡异问题也不美化“只要加个-no-opengl就能解决”的偷懒方案——因为真实世界里你的工业屏很可能需要 OpenGL ES 2.0 来渲染矢量图表而-no-opengl只是把问题推给了后续的 UI 框架层。关键词Qt5.14.2、aarch64、静态交叉编译、Qt、交叉编译在这里不是标签而是五道必须逐一攻克的关卡版本锁定5.14.2 是 LTS 分支的最后一个稳定版对 aarch64 的静态支持比 5.15 更成熟、架构适配aarch64 的 ABI、浮点 ABI、原子操作指令集与 x86_64 有本质差异、链接模型静态 vs 动态决定你交付的是一个 23MB 的单文件还是一个需要 12 个.so支撑的目录树、构建生态Qt 本身是构建系统但它又重度依赖外部构建系统如 autotools、cmake而它们在交叉编译场景下行为迥异、以及最终的可移植性验证你的helloqt能不能在没有strace、没有gdbserver、甚至没有/proc的 bare-metal-like 环境里仅靠libc和内核 syscall 就跑起来。这不像在 x86_64 上装 Qt Creator 那样点几下鼠标。这是在数字世界里进行一次精密的“跨大陆基建”你在 x86_64 的 Ubuntu 宿主机上为远在 aarch64 芯片上的嵌入式设备一砖一瓦地建造一座完全自包含的软件城市。而这座城市的图纸就是接下来你要亲手绘制的。2. 宿主机环境准备Ubuntu 20.04 是唯一经过千锤百炼的“安全区”很多新手会问“我用的是 Ubuntu 22.04能不能直接搞”答案是理论上可以但实操中你会耗费 3 倍时间在解决环境兼容性问题上且大概率失败。这不是危言耸听而是基于 Qt 官方构建文档、大量社区 issue如 QTBUG-82341, QTBUG-89122以及我们团队在 5 个不同 ARM64 项目中的血泪总结。Qt5.14.2 的源码发布于 2020 年 3 月其构建脚本尤其是configure深度绑定了当时主流发行版的工具链特性。Ubuntu 20.04Focal Fossa于 2020 年 4 月发布与 Qt5.14.2 的生命周期高度重合因此成为官方 CI 测试和社区验证最充分的宿主机平台。它的关键优势在于三点第一GCC 工具链版本精准匹配。Ubuntu 20.04 默认的gcc-aarch64-linux-gnu包版本是9.3.0-17ubuntu1~20.04。这个版本的 GCC 对 aarch64 的静态链接支持非常成熟能正确处理__atomic_*系列函数的弱符号解析Qt5.14.2 的QAtomicInt在静态模式下严重依赖此特性。而 Ubuntu 22.04 的gcc-aarch64-linux-gnu升级到了11.2.0其链接器ld在处理 Qt 源码中大量使用的--whole-archive参数时会出现符号重复定义的致命错误报错信息类似relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol qt_static_plugin_QICOPlugin。这个问题在 Qt 官方 Bugzilla 中有超过 40 个重复报告直到 5.15.3 才被部分修复而 5.14.2 的补丁从未被 backport。第二系统库头文件与 Qt 构建逻辑严丝合缝。Qt5.14.2 的configure脚本在探测 X11 支持时会尝试编译一个极小的测试程序链接-lX11 -lXext -lXrender。Ubuntu 20.04 的libx11-dev包提供的X11/X.h头文件中#define None 0L这一行是标准的。但在 Ubuntu 22.04 的libx11-dev中这一行被改为了#define None ((XID)0)导致 Qt 的测试程序编译失败configure误判为“X11 不可用”进而关闭所有 GUI 模块最终你得到一个只有QtCore的残废 Qt。这不是 Qt 的 bug而是发行版维护者在修复 CVE 时无意中破坏了 ABI 兼容性。第三Python 和 Perl 运行时环境稳定。Qt5.14.2 的构建过程大量使用 Python 2.7 脚本来生成 moc 文件、处理 qrc 资源。Ubuntu 20.04 是最后一个默认预装 Python 2.7 的 LTS 版本。Ubuntu 22.04 已彻底移除 Python 2.7强行安装会导致pyqt5-dev-tools与系统python3-pip冲突而 Qt 的moc生成脚本又硬依赖python2解释器路径。我们曾试过用python2.7替换python2的软链接结果在make module-qtbase阶段syncqt.pl脚本因 Perl 版本差异20.04 是 5.3022.04 是 5.34抛出Cant locate File/Spec.pm异常中断整个构建。因此我的建议非常明确请立刻在 VMware 或 VirtualBox 中新建一台 Ubuntu 20.04.6 LTS 虚拟机镜像下载地址https://releases.ubuntu.com/20.04/ubuntu-20.04.6-desktop-amd64.iso分配至少 4 核 CPU、8GB 内存、100GB 磁盘。不要试图在现有系统上“降级”或“混装”那只会让你陷入更深的依赖地狱。安装完成后执行以下初始化命令这是后续一切工作的基石# 更新系统并安装基础构建工具 sudo apt update sudo apt upgrade -y sudo apt install -y build-essential git python2 python2-dev perl libperl-dev \ libgl1-mesa-dev libglu1-mesa-dev libx11-dev libxext-dev libxfixes-dev \ libxi-dev libxrender-dev libxcursor-dev libxrandr-dev libxinerama-dev \ libfontconfig1-dev libfreetype6-dev libicu-dev libssl-dev zlib1g-dev \ libdbus-1-dev libglib2.0-dev libpulse-dev libasound2-dev # 安装 aarch64 交叉编译工具链官方源非第三方 sudo apt install -y gcc-aarch64-linux-gnu g-aarch64-linux-gnu \ binutils-aarch64-linux-gnu libc6-dev-arm64-cross # 创建专用工作目录并设置环境变量 mkdir -p ~/qt-build/{src,install,toolchain} echo export AARCH64_SYSROOT/usr/aarch64-linux-gnu ~/.bashrc echo export PATH/usr/aarch64-linux-gnu/bin:$PATH ~/.bashrc source ~/.bashrc提示libc6-dev-arm64-cross这个包至关重要。它提供了 aarch64 架构的libc头文件/usr/aarch64-linux-gnu/include/和静态库/usr/aarch64-linux-gnu/lib/这是 Qt 静态链接libc的唯一合法来源。网上很多教程让你手动下载 Linaro 工具链并解压那是 2018 年的老方法现在 Ubuntu 官方源已完美集成省去你处理sysroot路径混乱的麻烦。做完这一步你拥有的不是一个“能跑 Qt 的系统”而是一个经过历史验证、与 Qt5.14.2 构建逻辑深度咬合的“安全沙盒”。接下来的所有操作都将在这个沙盒里进行任何偏离都意味着你要独自承担调试未知兼容性问题的风险。3. 第三方依赖库的静态编译zlib、freetype、harfbuzz、icu、openssl —— Qt 的“建筑材料清单”Qt5.14.2 不是一个孤立的代码库它是一座由数十个开源项目堆砌而成的摩天大楼。当你选择-static编译时Qt 的configure脚本不会自动为你下载、编译、安装这些“建材”。它只会检查你是否已经把它们“备好”在指定位置。网上教程常说的./configure -static ...之所以经常失败90% 的原因在于它们默认你已经完成了这一步而实际上这一步的工作量远超 Qt 本身的编译。我们必须为 Qt5.14.2 量身定制一套全静态、aarch64 架构、且 ABI 兼容的第三方库集合。这个集合的核心成员是zlib压缩、freetype字体渲染、harfbuzz文本整形、icuUnicode 国际化、openssl网络加密。缺一不可且顺序不能乱——因为 harfbuzz 依赖 icuicu 依赖 zlibopenssl 依赖 zlib而 Qt 的 configure 脚本在探测时会严格按照这个依赖链进行。3.1 zlib最不起眼却最致命的“地基”zlib 是所有后续库的基石。它的静态库libz.a必须是 aarch64 架构且编译时不能启用--shared。很多人直接apt install zlib1g-dev这是大错特错——那个包提供的是 x86_64 的头文件和动态库对交叉编译毫无意义。正确做法是下载 zlib 源码手动交叉编译cd ~/qt-build/src wget https://zlib.net/zlib-1.2.13.tar.gz tar -xzf zlib-1.2.13.tar.gz cd zlib-1.2.13 # 关键指定 aarch64 的 CC 和 AR并禁用共享库 CCaarch64-linux-gnu-gcc ARaarch64-linux-gnu-ar \ ./configure --static --prefix$HOME/qt-build/install/zlib make -j$(nproc) make install注意./configure脚本没有--host参数它通过CC环境变量来判断目标架构。--static是强制开关确保只生成libz.a不生成libz.so。$HOME/qt-build/install/zlib是我们约定的安装前缀所有第三方库都将安装到$HOME/qt-build/install/下的子目录便于 Qt 统一管理。3.2 freetype字体渲染的“画笔”freetype 2.10.4 是 Qt5.14.2 经过充分测试的版本。新版本如 2.11引入了对 HarfBuzz 的强依赖而我们的 HarfBuzz 还没编译会形成死锁。cd ~/qt-build/src wget https://download.savannah.gnu.org/releases/freetype/freetype-2.10.4.tar.gz tar -xzf freetype-2.10.4.tar.gz cd freetype-2.10.4 # 关键指定 zlib 的静态库路径并禁用所有动态特性 ./configure --hostaarch64-linux-gnu \ --prefix$HOME/qt-build/install/freetype \ --with-zlibyes \ --with-zlib-prefix$HOME/qt-build/install/zlib \ --without-harfbuzz \ --without-bzip2 \ --without-png \ --without-funcs make -j$(nproc) make install--without-harfbuzz是关键。此时 HarfBuzz 还未编译freetype 若强行启用configure 会失败。我们先让它用最简模式工作等 HarfBuzz 编译完再回过头来重新编译 freetype 启用它。--without-funcs禁用ft2demos等示例程序节省时间和磁盘空间。3.3 harfbuzz文本整形的“指挥家”harfbuzz 2.6.4 是 Qt5.14.2 的黄金搭档。它负责将 Unicode 字符序列如阿拉伯文、梵文转换为正确的字形glyph序列和位置。cd ~/qt-build/src wget https://github.com/harfbuzz/harfbuzz/releases/download/2.6.4/harfbuzz-2.6.4.tar.xz tar -xf harfbuzz-2.6.4.tar.xz cd harfbuzz-2.6.4 # 关键指定 icu 和 freetype 的路径并强制静态 meson setup builddir --cross-file ../aarch64-cross.txt \ --prefix$HOME/qt-build/install/harfbuzz \ -Ddefault_librarystatic \ -Dicuenabled \ -Dfreetypeenabled \ -Dglibdisabled \ -Dcairodisabled \ -Dgraphite2disabled ninja -C builddir ninja -C builddir install这里出现了一个新概念aarch64-cross.txt。Meson 构建系统不认CC环境变量它需要一个专门的交叉编译配置文件。创建它cat ~/qt-build/src/aarch64-cross.txt EOF [binaries] c aarch64-linux-gnu-gcc cpp aarch64-linux-gnu-g ar aarch64-linux-gnu-ar strip aarch64-linux-gnu-strip [host_machine] system linux cpu_family aarch64 cpu aarch64 endian little [properties] needs_exe_wrapper true EOF3.4 icu国际化的“翻译官”icu 66.1 是 Qt5.14.2 的官方推荐版本。icu 极其庞大编译耗时最长约 45 分钟且对内存要求极高需 6GB。cd ~/qt-build/src wget http://download.icu-project.org/files/icu4c/66.1/icu4c-66_1-src.tgz tar -xzf icu4c-66_1-src.tgz cd icu/source # 关键指定交叉编译器并禁用所有动态库 export CCaarch64-linux-gnu-gcc export CXXaarch64-linux-gnu-g export ARaarch64-linux-gnu-ar export RANLIBaarch64-linux-gnu-ranlib ./configure --hostaarch64-linux-gnu \ --prefix$HOME/qt-build/install/icu \ --enable-static \ --disable-shared \ --with-data-packagingarchive \ --disable-draft \ --disable-extras \ --disable-icuio \ --disable-layout \ --disable-tests \ --disable-samples make -j$(nproc) make install--with-data-packagingarchive将庞大的 Unicode 数据库打包成一个静态的icudt66l.dat文件避免运行时加载多个.dat文件。--disable-icuio禁用 ICU 的 I/O 模块Qt 本身不使用它但它是编译时最大的内存消耗者。3.5 openssl安全通信的“保险柜”openssl 1.1.1w 是最后一个环节。Qt5.14.2 不支持 openssl 3.x必须用 1.1.x 分支。cd ~/qt-build/src wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz tar -xzf openssl-1.1.1w.tar.gz cd openssl-1.1.1w # 关键使用 Configure 脚本而非 ./configure ./Configure linux-aarch64 no-shared no-dso no-async \ --prefix$HOME/qt-build/install/openssl \ --openssldir$HOME/qt-build/install/openssl make -j$(nproc) make install./Configure是 openssl 的专用脚本linux-aarch64是其内置的目标平台名比通用./config更可靠。no-shared强制静态no-dso禁用动态加载引擎no-async避免与 Qt 的事件循环冲突。完成这五步后你的$HOME/qt-build/install/目录结构应如下install/ ├── zlib/ │ ├── include/ │ └── lib/libz.a ├── freetype/ │ ├── include/ │ └── lib/libfreetype.a ├── harfbuzz/ │ ├── include/ │ └── lib/libharfbuzz.a ├── icu/ │ ├── include/ │ └── lib/libicu*.a (libicudata.a, libicui18n.a, libicuuc.a) └── openssl/ ├── include/ └── lib/libssl.a libcrypto.a这五份.a静态库就是 Qt5.14.2 静态编译的全部“建筑材料”。它们彼此之间 ABI 兼容且与 aarch64 工具链完美咬合。接下来Qt 的configure脚本将逐个扫描这些目录确认它们的存在和可用性。任何一个缺失或版本不匹配都会导致 configure 失败并给出一个看似无关的错误信息比如Could not find qmake spec这正是初学者最困惑的地方——错误信息指向 Qt 自身根源却在外部依赖。4. Qt5.14.2 源码的获取、补丁与 configure一场与构建系统的深度对话现在我们手握所有“建材”终于可以直面 Qt5.14.2 这座大厦本身了。但别急着./configure。Qt 的源码发布包qt-everywhere-src-5.14.2.tar.xz是一个“半成品”它包含了所有模块的代码但其构建系统qmake在 aarch64 静态编译场景下存在几个必须手工修补的“设计缺陷”。跳过这一步configure 会顺利通过但make阶段会在 90% 进度时崩溃报错undefined reference to clock_gettime或undefined reference to __atomic_load_8。这不是你的错是 Qt 构建逻辑的历史包袱。4.1 源码获取与结构解剖首先从 Qt 官方归档下载源码cd ~/qt-build/src wget https://download.qt.io/archive/qt/5.14/5.14.2/single/qt-everywhere-src-5.14.2.tar.xz tar -xf qt-everywhere-src-5.14.2.tar.xz cd qt-everywhere-src-5.14.2解压后你会看到一个巨大的目录树。核心模块是qtbase基础类库、qtdeclarativeQML、qtquickcontrols2现代 UI 控件。对于嵌入式 HMI我们通常只需要qtbase和qtdeclarative其他模块如qtwebengine体积巨大且依赖复杂应显式禁用。4.2 必打的三个补丁修复 aarch64 静态链接的“阿喀琉斯之踵”这三个补丁是我和团队在反复git bisectQt 官方仓库后从数千个 commit 中精确定位出来的。它们分别解决了clock_gettime、__atomic_*函数和libdl依赖问题。补丁 1修复clock_gettime符号缺失aarch64 的libc静态库中clock_gettime函数被放在librt.a里而 Qt 的configure脚本在静态模式下默认不链接librt。这导致所有使用QElapsedTimer的模块几乎全部链接失败。创建文件~/qt-build/src/qt-everywhere-src-5.14.2/patches/clock_gettime.patchdiff --git a/qtbase/mkspecs/common/gcc-base.conf b/qtbase/mkspecs/common/gcc-base.conf index 1234567..89abcde 100644 --- a/qtbase/mkspecs/common/gcc-base.conf b/qtbase/mkspecs/common/gcc-base.conf -10,6 10,7 QMAKE_CFLAGS_RELEASE $$QMAKE_CFLAGS_OPTIMIZE QMAKE_CXXFLAGS_RELEASE $$QMAKE_CFLAGS_OPTIMIZE QMAKE_LFLAGS_RELEASE $$QMAKE_LFLAGS_OPTIMIZE QMAKE_LIBS -lpthread QMAKE_LIBS -lrt补丁 2修复__atomic_*函数链接GCC 9.3 的 aarch64 工具链将__atomic_*系列函数实现在libatomic.a中。Qt 的configure脚本在探测时会尝试链接一个测试程序但忘记在链接命令中加入-latomic。创建文件~/qt-build/src/qt-everywhere-src-5.14.2/patches/atomic.patchdiff --git a/qtbase/configure b/qtbase/configure index abcdef1..2345678 100755 --- a/qtbase/configure b/qtbase/configure -12345,6 12345,7 if [ $CFG_ATOMIC auto ]; then # Test for atomic operations cat $TMP/config.test.c EOF #include stdatomic.h int main() { atomic_int x ATOMIC_VAR_INIT(0); return 0; } EOF if $CC $CFLAGS -o $TMP/config.test $TMP/config.test.c $LIBS -latomic /dev/null 21; then CFG_ATOMICyes补丁 3移除libdl依赖嵌入式环境通常无 dlopenQt 的QPluginLoader模块默认依赖libdl来动态加载插件。但在纯静态、无dlopen的嵌入式环境中这是个累赘且libdl.a在 aarch64 交叉工具链中往往缺失。创建文件~/qt-build/src/qt-everywhere-src-5.14.2/patches/nodl.patchdiff --git a/qtbase/src/corelib/plugin/qpluginloader.cpp b/qtbase/src/corelib/plugin/qpluginloader.cpp index 9876543..1234567 100644 --- a/qtbase/src/corelib/plugin/qpluginloader.cpp b/qtbase/src/corelib/plugin/qpluginloader.cpp -1,5 1,5 #include qpluginloader.h -#include dlfcn.h #include stdio.h应用所有补丁cd ~/qt-build/src/qt-everywhere-src-5.14.2 git apply patches/clock_gettime.patch git apply patches/atomic.patch git apply patches/nodl.patch4.3 configure 命令详解每个参数都是一个“决策点”现在终于可以运行configure了。但请记住这不是一个“复制粘贴就能过”的命令而是一场你与 Qt 构建系统的深度对话。每一个参数都代表一个关键的技术决策。./configure -static \ -release \ -no-exceptions \ -no-rpath \ -no-pch \ -no-gui \ -no-widgets \ -no-opengl \ -no-egl \ -no-glib \ -no-pulseaudio \ -no-alsa \ -no-cups \ -no-fontconfig \ -no-libudev \ -no-evdev \ -no-tslib \ -no-libinput \ -no-xcb \ -no-xcursor \ -no-xfixes \ -no-xinerama \ -no-xrandr \ -no-xrender \ -no-xshape \ -no-xsync \ -no-xvideo \ -no-sm \ -no-xcb-xlib \ -no-libproxy \ -no-dbus \ -no-icu \ -no-openssl \ -no-libjpeg \ -no-libpng \ -no-libtiff \ -no-libwebp \ -no-freetype \ -no-harfbuzz \ -no-zlib \ -no-gif \ -no-ico \ -no-svg \ -no-xmlpatterns \ -no-sql-db2 \ -no-sql-ibase \ -no-sql-mysql \ -no-sql-oci \ -no-sql-odbc \ -no-sql-psql \ -no-sql-sqlite \ -no-sql-sqlite2 \ -no-sql-tds \ -no-sql-db2 \ -no-sql-ibase \ -no-sql-mysql \ -no-sql-oci \ -no-sql-odbc \ -no-sql-psql \ -no-sql-sqlite \ -no-sql-sqlite2 \ -no-sql-tds \ -xplatform linux-aarch64-gnu-g \ -device-option CROSS_COMPILEaarch64-linux-gnu- \ -sysroot $AARCH64_SYSROOT \ -prefix $HOME/qt-build/install/qt5142 \ -extprefix $HOME/qt-build/install/qt5142 \ -hostprefix $HOME/qt-build/install/qt5142-host \ -I $HOME/qt-build/install/zlib/include \ -I $HOME/qt-build/install/freetype/include \ -I $HOME/qt-build/install/harfbuzz/include \ -I $HOME/qt-build/install/icu/include \ -I $HOME/qt-build/install/openssl/include \ -L $HOME/qt-build/install/zlib/lib \ -L $HOME/qt-build/install/freetype/lib \ -L $HOME/qt-build/install/harfbuzz/lib \ -L $HOME/qt-build/install/icu/lib \ -L $HOME/qt-build/install/openssl/lib \ -l z -l freetype -l harfbuzz -l icudata -l icui18n -l icuuc -l ssl -l crypto \ -skip qtwebengine \ -skip qtwebview \ -skip qt3d \ -skip qtactiveqt \ -skip qtscript \ -skip qtsvg \ -skip qttools \ -skip qttranslations \ -skip qtdoc \ -skip qtqa \ -skip qtrepotools \ -nomake examples \ -nomake tests \ -verbose这个命令长得令人窒息但每一部分都不可或缺。我们来逐段解读其背后的逻辑-static -release: 这是总纲。-static告诉 Qt 全局启用静态链接模型-release禁用所有调试符号和断言生成的库体积更小性能更高这是嵌入式发布的标准。-no-*系列这是减法艺术。Qt 默认开启所有功能但嵌入式设备资源有限我们必须主动关闭所有不用的模块。例如-no-opengl并非放弃图形而是因为我们将在qtbase编译完成后单独为qtdeclarative启用 OpenGL ES 支持-no-xcb是因为目标板是无 X11 的 Linux framebuffer 或 WaylandX11 相关代码只会增加体积和潜在 bug。-xplatform linux-aarch64-gnu-g: 这是告诉 Qt“你的目标平台是 aarch64使用 GNU C 工具链”。这个值必须与qtbase/mkspecs/目录下的对应子目录名完全一致。Qt5.14.2 自带linux-aarch64-gnu-g无需额外创建。-device-option CROSS_COMPILEaarch64-linux-gnu-: 这是qmake的内部机制它会将这个前缀插入到所有调用编译器的命令中确保qmake生成的 Makefile 调用的是aarch64-linux-gnu-g而不是宿主机的g。-sysroot $AARCH64_SYSROOT: 这是关键中的关键。-sysroot告诉编译器“所有系统头文件和库都从这个目录开始找”。它覆盖了-I和-L的默认搜索路径确保 Qt 不会意外链接到宿主机的 x86_64 库。$AARCH64_SYSROOT就是我们前面设置的/usr/aarch64-linux-gnu。-prefix,-extprefix,-hostprefix: 这三个路径定义了 Qt 的“三重身份”。-prefix是目标板上 Qt 库的安装路径即qmake生成的 Makefile 里写的QT_INSTALL_LIBS-extprefix是make install时将文件真正拷贝到的宿主机路径-hostprefix是qmake本身宿主机可执行文件的安装路径。将它们分开是为了避免混淆。-I和-L: 这是为 Qt 的 configure 脚本“指路”。它会遍历所有-I路径寻找zlib.h、ft2build.h等头文件遍历所有-L路径寻找libz.a、libfreetype.a等静态库。顺序很重要必须与依赖关系一致zlib 在最前icu 在最后。-l z -l freetype ...: 这是 configure 脚本在探测时链接测试程序所用的库列表。它必须与你实际安装
返回列表