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
下载链接:https://pan.quark.cn/s/ce2fffc14cdf
提取码: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 个步骤按顺序做完)

步骤 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 分钟)

# 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 账号。

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

下载太慢的两个替代方案

# 方案 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 包

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 的硬前提)

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 环境的机器必做;其他机器无副作用)

# 临时清掉交叉变量(只在当前终端生效,不改任何配置文件)
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 建构建目录(干净起点)

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 不受影响,仅各国语言排序退化为码点序,
多数程序无感知)。

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

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

参数作用
-staticQt 全静态,程序单文件
-qt-xcbxcb 及 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(六项,错了就别往下走)

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

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

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

make -j$(nproc) 2>&1 | tee ../make-x86-static.log

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

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
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 坑的修复命令(仅在上面第二种情况发生时执行):

# 清掉构建树 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 安装

# 若之前装过旧版本,先清空安装目录(旧产物残留会被程序链入,不清白编;全新机器可跳过)
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 安装文件,之后链接程序时会报一串"跳过不兼容的"):

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

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

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 环境的机器做,全新机器跳过)

/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 提供)

ls /usr/lib64/libxkbcommon.a /usr/lib64/libxkbcommon-x11.a
# 预期:两行都列出

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

5.2 藏入口

mkdir -p /opt/qtwork/x86-so-hidden
mv /usr/lib64/libxkbcommon.so /usr/lib64/libxkbcommon-x11.so /opt/qtwork/x86-so-hidden/

5.3 验证

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

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

mv /opt/qtwork/x86-so-hidden/libxkbcommon*.so /usr/lib64/ && ldconfig

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

6.1 建 demo 源码

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 必须用全路径)

# 若当前终端 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 瘦身(可选,顺序不能反)

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

6.4 依赖总览

readelf -d demo | grep NEEDED

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

类别
显示/图形libEGL.so.1、libGL.so.1
字体libfontconfig.so.1、libfreetype.so.6
X11libX11.so.6、libX11-xcb.so.1、libXext.so.6、libSM.so.6、libICE.so.6
xcblibxcb.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 红线检查(一条命令,无输出 = 通过)

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*.soQt 不是静态的,qmake 用错了
libxkbcommon*步骤 5 的 .so 被还原了 → 重做步骤 5
libicu*编译时没带 -no-icu,或用错前缀 → 从步骤 4 重来
libglib* / libdbus* / xcb 碎片库误用了别的 Qt 或环境污染

6.6 冒烟测试

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

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

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

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


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

7.1 qmake 项目(三步)

# 前提:新终端,未 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 的源文件列表):

#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 一一对应):

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
)

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

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 initializedCMake 项目没加 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 mainqmake 不会自动收集目录里的 .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 自愈检查(兜底)
5vkb PCH 编译失败qtvirtualkeyboard 报 stdlib.h:75 fatal errorxorg proto 系列 .pc 注入 -I/usr/include,变 -isystem 后破坏 #include_next4.5.1 修复命令
6icu 拖 25MBNEEDED 多 libicui18n/uc/data 三项(约 25MB)Qt 默认链系统 icu4.3 首次编译就带 -no-icu
7xkbcommon 动态依赖NEEDED 多 libxkbcommon/xkbcommon-x11 两项ld 优先选 .so;Qt 无 -qt-xkbcommon 参数(源码树未内置)步骤 5 藏 .so 入口(对系统零影响,可逆)
8offscreen 冒烟假失败QT_QPA_PLATFORM=offscreen 跑 demo “已放弃”静态 demo 只链了 qxcb 平台插件,offscreen 插件不在内,qFatal 退出6.6 的"注意"
9gcc7 note bugstrip 报 corrupt GNU build attribute note: bad description sizegcc 7 生成损坏的 note section6.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/

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

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 版收工时同款结论)。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐