2026年10月

GCC、G++、CMake、Make、tar等基础工具独立安装,不包含在后续依赖安装过程中

gcc、g++建议使用目标平台提供的默认版本,不要使用高版本,容易因兼容问题导致编译出错

因使用不同的g++版本等原因,编译过程中需要根据报错对Qt源码存在的BUG进行修复。

编译构建分阶段进行:

- 基础SDK构建,编译构建重量级组件以外的基本内容,环境资源要求低、速度快

- 构建重量级组件,如QWebEngine,使用构建好的基础SDK进行编译构建

依赖安装

基础依赖

dnf install -y \
    perl \
    bison \
    flex \
    gperf \
    ruby \
    pkgconf-pkg-config \
    git \
    wget \
    tar \
    xz \
    libstdc++-static

检查:

gcc --version
g++ --version
perl --version
bison --version
flex --version
gperf --version

安装Python

Qt 5.15.2 需要Python 2.x

手动下载Python2源码包:

curl -LO https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz
tar xf Python-2.7.18.tgz
cd Python-2.7.18

构建并安装:

./configure \
    --prefix=/opt/python/2.7 \
    --enable-unicode=ucs4
    
make -j$(nproc)
make install

# 检查版本
/opt/python/2.7/bin/python2.7 --version

# 建立软连接
ln -sf /opt/python/2.7/bin/python /usr/bin/python
ln -sf /opt/python/2.7/bin/python /usr/bin/python2

# 导出到环境变量(临时)
export PATH=/opt/python/2.7/bin:$PATH

Qt GUI/X11 依赖

dnf install -y \
    mesa-libGL-devel \
    mesa-libEGL-devel \
    libX11-devel \
    libxcb-devel \
    libXext-devel \
    libXfixes-devel \
    libXi-devel \
    libXrender-devel \
    libXrandr-devel \
    libXcursor-devel \
    libXinerama-devel \
    libXcomposite-devel \
    libxcb-devel \
    xcb-util-devel \
    xcb-util-image-devel \
    xcb-util-keysyms-devel \
    xcb-util-renderutil-devel \
    xcb-util-wm-devel

然后:

dnf install -y \
    fontconfig-devel \
    freetype-devel \
    harfbuzz-devel \
    libpng-devel \
    libjpeg-turbo-devel

OpenGL / 输入设备相关

dnf install -y \
    libinput-devel \
    libudev-devel \
    dbus-devel \
    dbus-libs \
    alsa-lib-devel

OpenSSL

如果需要使用:

QtNetwork
QSslSocket
HTTPS
TLS

则安装:

dnf install -y \
    openssl-devel

确认:

openssl version

SQLite / PostgreSQL / MySQL

如果需要 Qt SQL 插件尽可能完整,可以安装:

dnf install -y \
    sqlite-devel

如果需要 PostgreSQL:

dnf install -y \
    postgresql-devel

MySQL/MariaDB:

dnf install -y \
    mariadb-connector-c-devel

QWebEngine依赖

已剔除前序安装过的依赖项
sudo dnf install -y \
    nss-devel \
    nspr-devel \
    pciutils-devel \
    ninja-build \
    cups-devel \
    pulseaudio-libs-devel \
    libcap-devel \
    libXtst-devel \
    libXScrnSaver-devel \
    libdrm-devel \
    libxkbcommon-devel \
    expat-devel

安装Node.js

5.15.2应当使用Node.js 12.18.0

下载:

wget https://nodejs.org/dist/v12.18.0/node-v12.18.0-linux-x64.tar.xz

安装:

sudo mkdir -p /opt/node
sudo tar -xJf node-v12.18.0-linux-x64.tar.xz -C /opt/node
# 导出到环境变量(临时)
export PATH=/opt/node/node-v12.18.0-linux-x64/bin:$PATH

检查:

which node
node --version

which npm
npm --version

应该得到:

/opt/node/node-v12.18.0-linux-x64/bin/node
v12.18.0

/opt/node/node-v12.18.0-linux-x64/bin/npm
6.14.4

源码兼容

一些在编译构建过程中会遇到的源码或构建工具链兼容性问题。

找不到std::max

找不到std::max等问题,直接在相关文件中增加#include

# 包括以下文件
vim ~/qt-everywhere-src-5.15.2/qtbase/src/corelib/global/qfloat16.h
vim ~/qt-everywhere-src-5.15.2/qtbase/src/corelib/text/qbytearraymatcher.h
vim ~/qt-everywhere-src-5.15.2/qtdeclarative/src/qmldebug/qqmlprofilerevent_p.h
vim ~/qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/perfetto/src/trace_processor/containers/string_pool.h

XCB兼容问题

cd ~/qt-everywhere-src-5.15.2/qtbase/src/platformsupport/input/xkbcommon

python3 - <<'PY'
from pathlib import Path

p = Path("qxkbcommon.cpp")
s = p.read_text()

anchor = '#include "qxkbcommon_p.h"'

compat = """
// Compatibility definitions for older libxkbcommon headers.
#ifndef XKB_KEY_dead_lowline
#define XKB_KEY_dead_lowline 0xfe90
#endif

#ifndef XKB_KEY_dead_aboveverticalline
#define XKB_KEY_dead_aboveverticalline 0xfe91
#endif

#ifndef XKB_KEY_dead_belowverticalline
#define XKB_KEY_dead_belowverticalline 0xfe92
#endif

#ifndef XKB_KEY_dead_longsolidusoverlay
#define XKB_KEY_dead_longsolidusoverlay 0xfe93
#endif
"""

if anchor not in s:
    raise SystemExit("错误:未找到插入位置,文件未修改。")

if "Compatibility definitions for older libxkbcommon headers." in s:
    raise SystemExit("兼容性定义已经存在,未重复修改。")

s = s.replace(anchor, anchor + "\n" + compat, 1)
p.write_text(s)

print("已添加兼容性定义。")
PY

QWebEngine编译

#原为
static const unsigned kSigStackSize = std::max(16384, SIGSTKSZ);

#改为
static const unsigned kSigStackSize =
    static_cast<unsigned>(std::max<unsigned>(16384, SIGSTKSZ));

#修改下述文件: 
vim ~/qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/breakpad/breakpad/src/client/linux/handler/exception_handler.cc

ffmpeg汇编问题

编译错误信息如下:

../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/autorename_libavcodec_flacdec.c -o obj/third_party/ffmpeg/ffmpeg_internal/autorename_libavcodec_flacdec.o
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h: Assembler messages:
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:116: 错误:operand type mismatch for `sar'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'
../../../qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h:125: 错误:operand type mismatch for `shr'

#修改下述文件
vim /root/qt-everywhere-src-5.15.2/qtwebengine/src/3rdparty/chromium/third_party/ffmpeg/libavcodec/x86/mathops.h

修改内容:将"ic"修改为"c"
static inline  int32_t NEG_SSR32( int32_t a, int8_t s){
    __asm__ ("sarl %1, %0\n\t"
         : "+r" (a)
         : "c" ((uint8_t)(-s))
    );
    return a;
}

#define NEG_USR32 NEG_USR32
static inline uint32_t NEG_USR32(uint32_t a, int8_t s){
    __asm__ ("shrl %1, %0\n\t"
         : "+r" (a)
         : "c" ((uint8_t)(-s))
    );
    return a;
}

构建

不要在源码目录里面构建。

基础SDK构建

创建独立构建目录:

mkdir -p ~/qt-build/5.15.2-openeuler-24.03-x86_64/base

创建安装目录:

mkdir -p /opt/qt/5.15.2/openeuler-24.03-x86_64

进入构建目录:

cd ~/qt-build/5.15.2-openeuler-24.03-x86_64/base

配置Qt:

~/qt-everywhere-src-5.15.2/configure \
    -prefix /opt/qt/5.15.2/openeuler-24.03-x86_64 \
    -opensource \
    -confirm-license \
    -release \
    -force-debug-info \
    -separate-debug-info \
    -shared \
    -nomake examples \
    -nomake tests \
    -skip qtwebengine \
    -skip qtwebview

参数说明:

-prefix 指定最终 SDK 安装位置。

-prefix /opt/qt/5.15.2/openeuler-24.03-x86_64

-opensource 使用开源版本

-confirm-license 自动接受开源许可证确认

-release 构建 Release Qt

-force-debug-info 生成Qt自身的调试信息

-separate-debug-info 调试信息独立存储

-shared

构建:

gmake -j$(nproc)

安装:

make install

验证qmake

/opt/qt/5.15.2/openeuler-24.03-x86_64/bin/qmake -v
/opt/qt/5.15.2/openeuler-24.03-x86_64/bin/moc -v
/opt/qt/5.15.2/openeuler-24.03-x86_64/bin/uic -v
/opt/qt/5.15.2/openeuler-24.03-x86_64/bin/rcc -v

构建WebEngine

创建独立构建目录:

mkdir -p ~/qt-build/5.15.2-openeuler-24.03-x86_64/webengine

创建安装目录:

mkdir -p /opt/qt/5.15.2/openeuler-24.03-x86_64

进入构建目录:

cd ~/qt-build/5.15.2-openeuler-24.03-x86_64/webengine

使用已经编译好的基础版本Qt:

export QT_ROOT=/opt/qt/5.15.2/openeuler-24.03-x86_64
export PATH=$QT_ROOT/bin:$PATH
export LD_LIBRARY_PATH=$QT_ROOT/lib:$LD_LIBRARY_PATH
export PKG_CONFIG_PATH="$QT_ROOT/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
export CMAKE_PREFIX_PATH="$QT_ROOT${CMAKE_PREFIX_PATH:+:$CMAKE_PREFIX_PATH}"

配置务必和基础SDK配置保持一致:

"$QT_ROOT/bin/qmake" \
    ~/qt-everywhere-src-5.15.2/qtwebengine \
    CONFIG+=release \
    CONFIG+=shared \
    CONFIG+=force_debug_info \
    CONFIG+=separate_debug_info

这里:

-prefix "$QT_ROOT"

非常重要。

它告诉 WebEngine:

最终安装位置就是我之前已经安装好的 Qt SDK。

所以:

Qt 基础模块
        ↓
/opt/qt/5.15.2/openeuler-24.03-x86_64

QtWebEngine
        ↓
/opt/qt/5.15.2/openeuler-24.03-x86_64

配置完成后,不要马上开始编译。

先检查它是否找到了已有 Qt。

可以看配置输出,或者:

grep -R "QT_INSTALL_PREFIX" config.summary config.log 2>/dev/null

更直接的是检查:

qmake -query

确保当前使用的是:

QT_VERSION:5.15.2

以及:

QT_INSTALL_PREFIX:/opt/qt/5.15.2/openeuler-24.03-x86_64

构建安装:

gmake -j$(nproc)
make install

安装后检查

首先:

find "$QT_ROOT" -iname '*WebEngine*' -o -iname '*webengine*'

重点应该能看到:

$QT_ROOT/bin/QtWebEngineProcess

$QT_ROOT/include/QtWebEngine
$QT_ROOT/include/QtWebEngineCore
$QT_ROOT/include/QtWebEngineWidgets

$QT_ROOT/lib/libQt5WebEngine.so
$QT_ROOT/lib/libQt5WebEngineCore.so
$QT_ROOT/lib/libQt5WebEngineWidgets.so

检查 WebEngine 的 Chromium 资源

这个非常重要。

执行:

find "$QT_ROOT" \
    \( -name '*.pak' -o -name '*icudtl*' \) \
    -print

应该能找到 WebEngine 相关资源。

同时:

find "$QT_ROOT" -name 'QtWebEngineProcess'

必须存在。

因为:

只看到 libQt5WebEngineCore.so 并不能证明 WebEngine SDK 安装完整。