Openeuler 24.03 源码编译Qt 5.15.2
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:$PATHQt 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-develOpenGL / 输入设备相关
dnf install -y \
libinput-devel \
libudev-devel \
dbus-devel \
dbus-libs \
alsa-lib-develOpenSSL
如果需要使用:
QtNetwork
QSslSocket
HTTPS
TLS则安装:
dnf install -y \
openssl-devel确认:
openssl versionSQLite / PostgreSQL / MySQL
如果需要 Qt SQL 插件尽可能完整,可以安装:
dnf install -y \
sqlite-devel如果需要 PostgreSQL:
dnf install -y \
postgresql-develMySQL/MariaDB:
dnf install -y \
mariadb-connector-c-develQWebEngine依赖
已剔除前序安装过的依赖项
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.hXCB兼容问题
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("已添加兼容性定义。")
PYQWebEngine编译
#原为
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.ccffmpeg汇编问题
编译错误信息如下:
../../../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 安装完整。