Qt 5.14.2 x86_64 静态编译 —— 从零搭建完整手册

Qt 5.14.2 x86_64 静态编译 ------ 从零搭建完整手册

声明:文章由AI编写,但内容经本人落地验证可行!

适用场景:在一台 x86_64 Linux (银河麒麟 V10 / openEuler 20.03 系)上,从零搭建一套 本地静态 Qt 编译环境 ,以后每个 Qt 项目都能编出单文件、零依赖部署的 x86 程序 (拷到任意 x86_64 Linux 桌面机直接运行,不需要装 Qt)。

全程约 1~1.5 小时(其中 Qt 编译约 1 小时无需值守)。 本手册自包含:全部操作都是直接在终端执行的命令,照抄即可,不需要创建任何脚本文件。

QT版本:5.14.2; 系统:Kylin Linux Advanced Server release V10 (Halberd); version 4.19.90-89.11.v2401.ky10.x86_64 下载链接:pan.quark.cn/s/ce2fffc14... 提取码:6rZE


第 0 章:开始之前

0.1 三个名词(3 分钟看懂)

名词 一句话解释
静态编译 把 Qt 库直接"焊"进你的程序里。产物是一个大文件,目标机不用装任何 Qt
动态依赖 程序运行时仍需要的少量系统库(X11、OpenGL 等)。这些必须保持动态,否则在别人机器上画不出窗口
前缀(prefix) 这套静态 Qt 安装到哪。本文用 /opt/qt5.14.2-x86_64-static,与系统的、交叉的 Qt 互不干扰

0.2 与"ARM 交叉编译"的区别(如果你搭过那套)

ARM 交叉版 x86 本地版(本手册)
产出 ARM 目标机跑的程序 x86 机器跑的程序
编译器 aarch64-linux-gnu-g++ 本机 g++
sysroot / 工具链文件 需要 全部不需要
步骤 多(工具链→sysroot→.pc 清理→...) (6 个步骤做完)
依赖白名单 19 项 18 项

0.3 环境要求自查表

项目 要求 不满足怎么办
系统 x86_64 Linux(麒麟 V10/openEuler 20.03 同系最佳) 先换机或确认 glibc ≥ 2.17
用户 root(或 sudo) ---
磁盘 /opt 下 ≥ 15GB 空闲(源码 3GB + 构建 6GB + 安装 2GB) 清理或换分区
内存 ≥ 4GB(8GB 更稳,-j8 编译峰值大) 内存小就用 -j4(见附录 A 第 3 条)
网络 能访问 download.qt.io + yum 源可用 见步骤 2 的备用下载方案;yum 见步骤 3 失败处理
终端 全新终端,未 source 任何交叉 profile 这是全流程的隐形前提,见步骤 1

0.4 流程总览(6 个步骤按顺序做完)

ini 复制代码
步骤 1  环境准备(确认终端干净、磁盘够、建工作目录)
步骤 2  下载 Qt 5.14.2 源码(官方直链 + md5 校验 + 解压)
步骤 3  安装依赖(yum 装 -devel 包 + 逐项确认在位)
步骤 4  编译 Qt(configure 带 -no-icu → make → install,约 1 小时)
步骤 5  藏 xkbcommon 链接入口(1 分钟,程序少 2 个动态依赖)
步骤 6  demo 验收(预期 NEEDED = 18 个,零红线)
        │
        ▼
   日常使用:新项目 5 分钟出包(第七章)

若机器上已有 ARM 交叉编译环境:本手册所有命令都做了隔离设计(独立前缀、独立构建树、 每步先净化环境、结尾复查交叉环境),照做不会破坏它。


步骤 1:环境准备(2 分钟)

bash 复制代码
# 1. 切 root
su - root

# 2. 【关键】确认当前终端是"干净"的
gcc -dumpmachine
# 预期输出:x86_64-linux-gnu
# 若输出 aarch64-xxx 或报错 command not found:
#   说明 source 过 /etc/profile.d/cross-aarch64.sh → 开一个新终端重来

# 3. 确认磁盘
df -h /opt
# 预期:可用 ≥ 15GB

# 4. 建工作目录
mkdir -p /opt/qtwork && cd /opt/qtwork

⚠️ 唯一的铁律 :编 x86 的整个过程中,任何终端都不要 source 交叉环境 (如果这台机器搭过 ARM 交叉编译)。一旦混入,pkg-config 会解析到 ARM 的库, 轻则链接报"跳过不兼容的",重则编出废件。步骤 4 里也有检查命令兜底,但提前避开最省事。


步骤 2:下载 Qt 源码(约 10 分钟)

国内镜像(清华/中科大/上交等)已全部裁剪 5.14 老版本归档,只有官方主站还有。 archive 直链不需要 Qt 账号。

bash 复制代码
cd /opt/qtwork

# 2.1 下载(约 524MB;wget -c 支持断点续传,中断后重敲同一条命令即可接着下)
wget -c https://download.qt.io/archive/qt/5.14/5.14.2/single/qt-everywhere-src-5.14.2.tar.xz

# 2.2 校验完整性(必须一致再继续)
md5sum qt-everywhere-src-5.14.2.tar.xz
# 预期输出:b3d2b6d00e6ca8a8ede6d1c9bdc74daf  qt-everywhere-src-5.14.2.tar.xz
# 不一致 = 文件损坏,rm 删掉后重新下载

# 2.3 解压(约 1~2 分钟)
tar -xJf qt-everywhere-src-5.14.2.tar.xz

# 2.4 确认解压成功
ls qt-everywhere-src-5.14.2/configure
# 预期输出:qt-everywhere-src-5.14.2/configure

下载太慢的两个替代方案

bash 复制代码
# 方案 A:多线程下载(装了 aria2 的话)
aria2c -x 8 -s 8 https://download.qt.io/archive/qt/5.14/5.14.2/single/qt-everywhere-src-5.14.2.tar.xz

# 方案 B:从已搭好的机器整目录打包拷来(最快,5 分钟)
# 在老机器上执行:
#   tar -cJf qt-src.tar.xz -C /opt/qtwork qt-everywhere-src-5.14.2
#   scp qt-src.tar.xz root@新机器:/opt/qtwork/
# 在新机器上解压后,直接进入步骤 3

步骤 3:安装依赖(2 分钟)

3.1 一条命令装齐全部 -devel 包

bash 复制代码
yum install -y gcc gcc-c++ make perl \
    openssl-devel zlib-devel \
    freetype-devel fontconfig-devel \
    libxcb-devel libX11-devel libXext-devel \
    libSM-devel libICE-devel \
    mesa-libGL-devel mesa-libEGL-devel \
    libxkbcommon-devel libxkbcommon-x11-devel

说明:-qt-xcb 会在编译时内置 xcb-util 全家桶(icccm/image/keysyms/...), 所以不用单独装那一串 xcb-util 包;这里装的都是 Qt 真正的外部依赖。 yum 幂等,重复执行安全。

3.2 逐项确认关键文件在位(configure 的硬前提)

bash 复制代码
ls /usr/include/openssl/ssl.h /usr/lib64/libssl.a /usr/lib64/libcrypto.a \
   /usr/include/zlib.h \
   /usr/include/freetype2/freetype/freetype.h \
   /usr/include/fontconfig/fontconfig.h \
   /usr/include/X11/Xlib.h /usr/include/X11/Xlib-xcb.h \
   /usr/include/xcb/xcb.h /usr/include/GL/gl.h \
   /usr/include/xkbcommon/xkbcommon-x11.h \
   /usr/lib64/libGL.so /usr/lib64/libEGL.so /usr/lib64/libSM.so

预期结果 :所有文件路径原样列出,没有任何一行 不存在 / No such file

失败现象 处理
有包装不上 + 对应文件缺失 yum 源问题:挂本系统 x86_64 安装 ISO 做本地源(mount -o loop Kylin-*.iso /mnt 后配置 repo),装上对应包后重跑 3.2 确认
libEGL.so 缺失 非致命(configure 会自动关闭对应特性),但建议装上 mesa-libEGL-devel

步骤 4:编译 Qt(约 1 小时,其中 make 阶段无需值守)

4.1 环境净化(防交叉污染,搭过 ARM 环境的机器必做;其他机器无副作用)

bash 复制代码
# 临时清掉交叉变量(只在当前终端生效,不改任何配置文件)
unset PKG_CONFIG_PATH PKG_CONFIG_LIBDIR PKG_CONFIG_SYSROOT_DIR CC CXX \
      CFLAGS CXXFLAGS LDFLAGS

# 把 bootlin(交叉工具链目录)从当前终端的 PATH 里剔除
export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v bootlin | paste -sd:)

# 三项确认
which pkg-config   # 预期:/usr/bin/pkg-config
gcc -dumpmachine   # 预期:x86_64-linux-gnu
ls /opt/qtwork/qt-everywhere-src-5.14.2/configure   # 预期:路径原样列出

4.2 建构建目录(干净起点)

bash 复制代码
cd /opt/qtwork
rm -rf build-x86-static
mkdir -p build-x86-static && cd build-x86-static

rm -rf 是为了清掉可能存在的历史半成品(configure 中断会留下残缺状态污染下次构建)。 全新机器上这个目录本来就不存在,命令同样安全。

4.3 configure(核心命令,注意两点)

⚠️ 注意一 :源码根目录的 configure 是一个"转发器",它自己会转给 qtbase/configure 并自动加 -top-level 参数------所以这里不能再传 -top-level , 传了会报 Unknown command line option(实测踩过的坑)。

⚠️ 注意二-no-icu 必须在第一次编译就带上(作用:去掉 icu 三个约 25MB 的 动态依赖;QRegularExpression 正则走内置 pcre 不受影响,仅各国语言排序退化为码点序, 多数程序无感知)。

bash 复制代码
cd /opt/qtwork/build-x86-static

/opt/qtwork/qt-everywhere-src-5.14.2/configure \
    -opensource -confirm-license -release -static \
    -prefix /opt/qt5.14.2-x86_64-static -extprefix /opt/qt5.14.2-x86_64-static \
    -nomake tests -nomake examples \
    -skip qtwebengine -skip qtwebview -skip qtwebchannel -skip qtwayland -skip qtscript -skip qtgamepad \
    -skip qtspeech -skip qtremoteobjects -skip qtscxml -skip qtlottie -skip qtdatavis3d \
    -skip qtsensors -skip qtlocation -skip qtserialbus -skip qtconnectivity -skip qtpurchasing -skip qtquick3d \
    -xcb -qt-xcb -xcb-xlib -fontconfig -system-freetype \
    -openssl-linked -opengl desktop -linuxfb -evdev \
    -no-eglfs -no-dbus -no-glib -no-icu \
    -qt-libpng -qt-libjpeg -qt-harfbuzz -qt-pcre -qt-zlib -sql-sqlite \
    -no-warnings-are-errors \
    2>&1 | tee ../configure-x86-static.log

参数速览(为什么是这些):

参数 作用
-static Qt 全静态,程序单文件
-qt-xcb xcb 及 14 个子库全部编进 Qt,消除一堆动态依赖
-no-dbus / -no-glib / -no-eglfs 各砍掉一串传递依赖(dbus→systemd→gcrypt...、glib→pcre/ffi...、eglfs→drm/gbm)
-no-icu 去掉 icu 三个动态依赖(约 25MB)
-qt-libpng -qt-libjpeg -qt-harfbuzz -qt-pcre -qt-zlib 这些第三方库用 Qt 内置源码,不链系统的
16 个 -skip 裁掉嵌入式不可行/罕用模块(webengine、wayland、sensors 等)

4.4 核对 config.summary(六项,错了就别往下走)

bash 复制代码
grep -E "Qt D-Bus|GLib |OpenSSL |directly linked|Desktop OpenGL|EGLFS|XCB XKB" config.summary
关键项 期望值 含义
Qt D-Bus ............................... no no 故意关掉(省一串传递依赖)
GLib ................................... no no 故意关掉
OpenSSL ................................ yes yes openssl-linked 生效
Qt directly linked to OpenSSL ........ yes yes OpenSSL 直接链入
Desktop OpenGL ....................... yes yes OpenGL 支持
EGLFS .................................. no no 故意关掉(xcb 桌面用不到)
XCB XKB .............................. yes yes 键盘支持,必须 yes,否则程序没键盘输入

XCB XKB 是 no:说明步骤 3 的 libxkbcommon-x11-devel 没装上,回去重装再从 4.2 重来。

4.5 make(约 1 小时,无需值守)

bash 复制代码
make -j$(nproc) 2>&1 | tee ../make-x86-static.log

编译期间想看进度(另开一个终端,不影响编译):

bash 复制代码
tail -3 /opt/qtwork/make-x86-static.log           # 进度(模块名会滚动变化)
grep -cE "error:" /opt/qtwork/make-x86-static.log # 0 = 健康
free -h                                           # 内存水位

make 失败时的两种已知情况(按现象对号入座)

| 现象 | 处理 |
|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|------------------------------------------------|
| make 莫名消失 / 退出码 137 | 内存不足(OOM)。直接敲 `make -j4 2>&1 | tee -a ../make-x86-static.log` 续编(已编完的模块不会重编) |
| qtvirtualkeyboard 报 cstdlib:75: fatal error: stdlib.h | 已知 PCH 坑(xorg proto 系列 .pc 注入的 -I/usr/include 变成 -isystem 后破坏 gcc 的 #include_next)。执行下面 4.5.1 的修复命令后续编 |
| 其他报错 | 把 tail -60 /opt/qtwork/make-x86-static.log 的输出贴出来排查 |

4.5.1 PCH 坑的修复命令(仅在上面第二种情况发生时执行):

bash 复制代码
# 清掉构建树 Makefile 里的 -isystem /usr/include(锚定匹配,不伤子目录形式)
find /opt/qtwork/build-x86-static -name Makefile -exec \
    sed -i 's@-isystem /usr/include\( \|$\)@ @g' {} +

# 续编(增量,已编完的模块不重编)
cd /opt/qtwork/build-x86-static
make -j$(nproc) 2>&1 | tee -a ../make-x86-static.log

4.6 安装

bash 复制代码
# 若之前装过旧版本,先清空安装目录(旧产物残留会被程序链入,不清白编;全新机器可跳过)
rm -rf /opt/qt5.14.2-x86_64-static

cd /opt/qtwork/build-x86-static
make install 2>&1 | tee ../install-x86-static.log

# 安装验证一:qmake 版本
/opt/qt5.14.2-x86_64-static/bin/qmake -v
# 预期两行:QMake version 3.1 / Using Qt version 5.14.2 in /opt/qt5.14.2-x86_64-static/lib

# 安装验证二:五个核心库
ls -lh /opt/qt5.14.2-x86_64-static/lib/libQt5Core.a \
       /opt/qt5.14.2-x86_64-static/lib/libQt5Gui.a \
       /opt/qt5.14.2-x86_64-static/lib/libQt5Widgets.a \
       /opt/qt5.14.2-x86_64-static/lib/libQt5VirtualKeyboard.a \
       /opt/qt5.14.2-x86_64-static/plugins/platforms/libqxcb.a
# 预期:5 行全部列出(大小约 14M/15M/17M/1.4M/13K)

4.7 自愈检查:安装文件里有没有烙进交叉 sysroot 路径

这一步只对搭过 ARM 交叉环境的机器有意义(若 configure 阶段 PATH 混入过交叉 pkg-config,ARM 库路径会被烙进 Qt 安装文件,之后链接程序时会报一串"跳过不兼容的"):

bash 复制代码
# 检查(预期:无任何输出)
grep -rl -- "-L/opt/bootlin" /opt/qt5.14.2-x86_64-static --include='*.prl' --include='*.pri'

若有输出,执行清理(只剔除 -L 路径,不影响库依赖本身):

bash 复制代码
grep -rl -- "-L/opt/bootlin" /opt/qt5.14.2-x86_64-static --include='*.prl' --include='*.pri' | \
    xargs -r sed -i 's@-L/opt/bootlin[^ ]*@@g'

4.8 交叉环境复查(搭过 ARM 环境的机器做,全新机器跳过)

bash 复制代码
/opt/qt5.14.2-aarch64-static-xcb/bin/qmake -v   # 预期:仍正常输出版本信息
ls -d /opt/qtwork/build-desktop-full             # 预期:目录仍存在

步骤 5:藏 xkbcommon 链接入口(1 分钟,程序少 2 个动态依赖)

做什么 :把 /usr/lib64 里两个无版本号的 .so 链接入口 挪走,让链接器只能选 devel 包自带的静态库 .a

原理 :静态 Qt 的库里留着 xkb_* 未定义符号,真正决定链 .so 还是 .a 的时刻是 你编最终程序的那次链接 ------两者都在时 ld 永远优先选 .so。Qt 源码树没内置 xkbcommon(不存在 -qt-xkbcommon 参数),所以"藏 .so 入口"就是标准做法。 只藏链接器入口,运行时真身 libxkbcommon.so.0 原地不动------系统里已运行/之后运行的 程序完全不受影响,只影响"之后新发生的链接"。

5.1 确认静态库在位(libxkbcommon-devel 提供)

bash 复制代码
ls /usr/lib64/libxkbcommon.a /usr/lib64/libxkbcommon-x11.a
# 预期:两行都列出

若报不存在:说明 devel 包没带静态库,跳过整个步骤 5 也可以(程序会多 2 个 xkbcommon 动态依赖,x86 桌面机器都自带,不影响运行)。

5.2 藏入口

bash 复制代码
mkdir -p /opt/qtwork/x86-so-hidden
mv /usr/lib64/libxkbcommon.so /usr/lib64/libxkbcommon-x11.so /opt/qtwork/x86-so-hidden/

5.3 验证

bash 复制代码
ls /usr/lib64/libxkbcommon.so /usr/lib64/libxkbcommon-x11.so
# 预期:No such file or directory(藏匿生效)

恢复动态链接(如需还原系统默认)

bash 复制代码
mv /opt/qtwork/x86-so-hidden/libxkbcommon*.so /usr/lib64/ && ldconfig

步骤 6:demo 验收(2 分钟)

6.1 建 demo 源码

bash 复制代码
mkdir -p /opt/qtwork/demo-x86 && cd /opt/qtwork/demo-x86

cat > main.cpp <<'EOF'
#include <QtWidgets/QApplication>
#include <QtWidgets/QLabel>
int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    QLabel l(QStringLiteral("Qt 5.14.2 x86_64 静态编译 OK"));
    l.resize(420, 120);
    l.show();
    return app.exec();
}
EOF

cat > demo.pro <<'EOF'
TARGET = demo
QT += widgets
CONFIG += release
SOURCES += main.cpp
EOF

⚠️ SOURCES += main.cpp 不能漏 ------qmake 不会自动收集目录里的 .cpp, 漏了链接会报 undefined reference to main(实测踩过的坑)。

6.2 编译(qmake 必须用全路径)

bash 复制代码
# 若当前终端 source 过交叉环境,先净化(同 4.1 的三条)
unset PKG_CONFIG_PATH PKG_CONFIG_LIBDIR PKG_CONFIG_SYSROOT_DIR CC CXX CFLAGS CXXFLAGS LDFLAGS
export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v bootlin | paste -sd:)

/opt/qt5.14.2-x86_64-static/bin/qmake
make -j$(nproc)

6.3 瘦身(可选,顺序不能反)

bash 复制代码
# gcc7 的 note bug:必须先移除该 section 再 strip
objcopy --remove-section .gnu.build.attributes demo
strip demo
ls -lh demo

6.4 依赖总览

bash 复制代码
readelf -d demo | grep NEEDED

验收标准------18 项白名单(NEEDED 只能是这些,实测基线):

类别
显示/图形 libEGL.so.1、libGL.so.1
字体 libfontconfig.so.1、libfreetype.so.6
X11 libX11.so.6、libX11-xcb.so.1、libXext.so.6、libSM.so.6、libICE.so.6
xcb libxcb.so.1、libxcb-glx.so.0
C 运行时 libc.so.6、libm.so.6、libdl.so.2、libpthread.so.0、libstdc++.so.6、libgcc_s.so.1、ld-linux-x86-64.so.2

6.5 红线检查(一条命令,无输出 = 通过)

bash 复制代码
readelf -d demo | grep -E "libQt5|libdbus|libglib|libgthread|libffi|libdrm|libicu|libxkbcommon|libxcb-icccm|libxcb-image|libxcb-keysyms|libxcb-randr|libxcb-render|libxcb-shape|libxcb-sync|libxcb-xfixes|libxcb-xinerama|libxcb-xinput"
红线项(若出现) 含义
任何 libQt5*.so Qt 不是静态的,qmake 用错了
libxkbcommon* 步骤 5 的 .so 被还原了 → 重做步骤 5
libicu* 编译时没带 -no-icu,或用错前缀 → 从步骤 4 重来
libglib* / libdbus* / xcb 碎片库 误用了别的 Qt 或环境污染

6.6 冒烟测试

bash 复制代码
# 有桌面环境(DISPLAY 存在)时:直接跑,窗口正常弹出即通过
./demo

# 无桌面环境时:拷到任意 x86_64 桌面机再验证
scp demo 用户@某桌面机:~/    # 然后在桌面机上 ./demo

注意:不要用 QT_QPA_PLATFORM=offscreen 测------静态 demo 只链入了 qxcb 平台插件, offscreen 插件不在内,会 qFatal 退出(表现为"已放弃"),这是插件缺失不是程序问题。

验收全过 = 环境搭建完成。 部署:单文件 scp 到任意 x86_64 Linux 桌面机直接运行,零配置。


第七章:日常使用(以后每个新项目 5 分钟出包)

7.1 qmake 项目(三步)

bash 复制代码
# 前提:新终端,未 source 交叉 profile
cd /opt/qtwork/myapp
/opt/qt5.14.2-x86_64-static/bin/qmake myapp.pro    # 必须全路径,防误用别的 qmake
make -j$(nproc)

# 可选瘦身(顺序不能反):
objcopy --remove-section .gnu.build.attributes myapp
strip myapp

# 验收(30 秒,白名单/红线见步骤 6):
readelf -d myapp | grep NEEDED

7.2 CMake 项目

qmake 会自动把平台插件/图片插件"焊"进程序,CMake 不会 ------不补的话编译能过、 运行报 no Qt platform plugin could be initialized。需要补两样(内容全部给全):

① 新建 plugin_import.cpp(加进 add_executable 的源文件列表):

cpp 复制代码
#include <QtPlugin>

/* 平台插件(必须)------窗口能在 X11 桌面显示全靠它 */
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)

/* GL 集成插件(2 个,必须)------OpenGL 渲染路径(GLX/EGL)的桥接 */
Q_IMPORT_PLUGIN(QXcbEglIntegrationPlugin)
Q_IMPORT_PLUGIN(QXcbGlxIntegrationPlugin)

/* 图片格式插件:8 个全上。全加零风险------静态库不增加动态依赖,只多 1~2MB 体积 */
Q_IMPORT_PLUGIN(QGifPlugin)      // gif
Q_IMPORT_PLUGIN(QICNSPlugin)     // icns(注意 QICNS 全大写)
Q_IMPORT_PLUGIN(QICOPlugin)      // ico/cur(注意 QICO 全大写)
Q_IMPORT_PLUGIN(QJpegPlugin)     // jpg/jpeg
Q_IMPORT_PLUGIN(QTgaPlugin)      // tga(注意 QTga 大小写)
Q_IMPORT_PLUGIN(QTiffPlugin)     // tiff/tif
Q_IMPORT_PLUGIN(QWbmpPlugin)     // wbmp
Q_IMPORT_PLUGIN(QWebpPlugin)     // webp

② CMakeLists.txt 追加(插件目标与 Q_IMPORT_PLUGIN 一一对应):

cmake 复制代码
target_link_libraries(myapp PRIVATE
    Qt5::Widgets
    Qt5::QXcbIntegrationPlugin
    Qt5::QXcbEglIntegrationPlugin
    Qt5::QXcbGlxIntegrationPlugin
    Qt5::QGifPlugin
    Qt5::QICNSPlugin
    Qt5::QICOPlugin
    Qt5::QJpegPlugin
    Qt5::QTgaPlugin
    Qt5::QTiffPlugin
    Qt5::QWbmpPlugin
    Qt5::QWebpPlugin
)

③ 编译命令(不需要任何工具链文件):

bash 复制代码
cd /opt/qtwork/myapp
mkdir -p build-x86 && cd build-x86
cmake .. \
  -DCMAKE_PREFIX_PATH=/opt/qt5.14.2-x86_64-static \
  -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

7.3 常见问题速查

现象 原因与解决
编出的程序拷到别的 x86 机器"无法执行" 用了交叉 qmake(编出的是 ARM 程序),检查 qmake 全路径
链接报一串 跳过不兼容的 .../bootlin/... source 过交叉 profile。开新终端,并按 6.2 的两条命令净化环境后重编
NEEDED 出现 libxkbcommon.so.0 步骤 5 的 .so 被还原 → 重做步骤 5;不重藏也能跑(桌面机自带)
NEEDED 出现 libicu* 编译时没带 -no-icu,或用错了 Qt 前缀
strip 报 corrupt GNU build attribute note 先 objcopy 去 note 再 strip(顺序不能反)
cmake 改环境后结果诡异 rm -rf build-x86 重来(CMake 缓存了旧编译器路径)
运行报 no Qt platform plugin could be initialized CMake 项目没加 plugin_import.cpp / 没链插件目标
想用 WebEngine / dbus 模块 编译时被 skip / -no-dbus,没有。可用:Widgets、Quick/QML、Charts、SVG、Network、SerialPort、Multimedia、VirtualKeyboard、Sql+SQLite 等

附录 A:踩坑全记录(每条的解法都已固化在手册步骤里,照做不会踩)

# 现象 根因 手册里固化在哪
1 -top-level 不能手传 configure 秒退 Unknown command line option '-top-level' tarball 根目录的 configure 是转发器,自己会加 -top-level,再传就重复 步骤 4.3 的"注意一"
2 .pro 漏 SOURCES 链接报 undefined reference to main qmake 不会自动收集目录里的 .cpp 步骤 6.1 的 demo.pro(含 SOURCES)+ 警告
3 内存不足 make 静默消失 / 退出码 137 -j8 编译峰值内存超限 4.5 故障表:make -j4 续编即可
4 交叉环境污染 .prl 链接行混入 -L/opt/bootlin-...,ld 报"跳过不兼容" configure 期 PATH 里的交叉 pkg-config 把 ARM 库路径烙进 Qt 安装文件 4.1 净化环境(治本)+ 4.7 自愈检查(兜底)
5 vkb PCH 编译失败 qtvirtualkeyboard 报 stdlib.h:75 fatal error xorg proto 系列 .pc 注入 -I/usr/include,变 -isystem 后破坏 #include_next 4.5.1 修复命令
6 icu 拖 25MB NEEDED 多 libicui18n/uc/data 三项(约 25MB) Qt 默认链系统 icu 4.3 首次编译就带 -no-icu
7 xkbcommon 动态依赖 NEEDED 多 libxkbcommon/xkbcommon-x11 两项 ld 优先选 .so;Qt 无 -qt-xkbcommon 参数(源码树未内置) 步骤 5 藏 .so 入口(对系统零影响,可逆)
8 offscreen 冒烟假失败 QT_QPA_PLATFORM=offscreen 跑 demo "已放弃" 静态 demo 只链了 qxcb 平台插件,offscreen 插件不在内,qFatal 退出 6.6 的"注意"
9 gcc7 note bug strip 报 corrupt GNU build attribute note: bad description size gcc 7 生成损坏的 note section 6.3 瘦身顺序(先 objcopy 后 strip)
10 安装残留混链 重编后程序仍链入旧库 安装目录没清空,旧 .a 残留 4.6 安装前 rm -rf 前缀

附录 B:产物清单与回滚

这套环境的全部"资产"

路径 内容 可否删
/opt/qt5.14.2-x86_64-static/ 静态 Qt 本体(核心资产 ❌ 删了就要重跑步骤 4
/opt/qtwork/qt-everywhere-src-5.14.2/ Qt 源码(约 3GB) ✅ 可删(重编时需重下/重拷)
/opt/qtwork/build-x86-static/ 构建树(约 6GB) ✅ 可删(只是缓存,重编会重建)
/opt/qtwork/x86-so-hidden/ 藏起来的 xkbcommon .so 入口 ⚠️ 删前先 mv/usr/lib64/

完全回滚(卸载这套环境)

bash 复制代码
mv /opt/qtwork/x86-so-hidden/libxkbcommon*.so /usr/lib64/ 2>/dev/null; ldconfig   # 先还系统库
rm -rf /opt/qt5.14.2-x86_64-static /opt/qtwork/build-x86-static /opt/qtwork/demo-x86
# 可选:连源码一起删
# rm -rf /opt/qtwork/qt-everywhere-src-5.14.2

(已搭过 ARM 交叉环境的机器:上述命令不碰 /opt/qt5.14.2-aarch64-static-xcb/opt/qtwork/build-desktop-full/opt/bootlin-*,交叉环境完好。)

附录 C:为什么有些库保持动态

依赖 为什么必须动态
X11 / xcb ×7 要与目标机 X server 对话,静态化直接跑不了
GL / EGL 要匹配目标机 GPU 驱动
fontconfig / freetype 所有 Linux 桌面 100% 自带,静态化需源码编译,零收益
glibc / libstdc++ 全静态有 NSS/dlopen 隐患且无兼容性收益

这 18 个就是实际最优解(ARM 版收工时同款结论)。

相关推荐
企业数字化笔记3 小时前
固定资产历史数据怎么导入系统?Excel模板、字段映射和数据校验
android·java·数据库·后端
西瓜太郎12343 小时前
request_id 如何串起请求、路由、计费和日志
后端·python
by组态3 小时前
Ricon组态系统通信配置指南
前端·后端·物联网
sbjdhjd3 小时前
ThinkPHP 5.0.10 缓存写入型 RCE 复盘:从手动搭建、换行绕过到源码单步验证 | 05
java·后端·安全·spring·网络安全·数据挖掘·php
LEE3 小时前
Agent 的控制权,为什么正在回到模型手里?
前端·后端
沃夫上校3 小时前
跨域这件事,其实浏览器在替你挡刀
前端·后端·nginx
用户298698530143 小时前
Python 将 Word 文档转换为图片的实践指南
后端·python·api
旺仔不是程序员3 小时前
致命索引失效:索引列运算与函数索引不匹配
数据库·后端·面试
老孙讲技术3 小时前
把连锁门店轮询抓拍和遮挡叫醒接进督导台-setDeviceSnapEnhanced与setMessageCallback
后端·物联网·音视频开发