实践指南-011-qt源码编译

type
status
date
slug
summary
tags
category
icon
password
Qt 编译需要的耐心与细心,相比于枯燥的等待,最麻烦的还是当错误发生时,如何根据现场进行调整。

1. 官方资源

  • 建立Qt源:https://doc.qt.io/qt-5/build-sources.html
  • 配置Qt编译选项:https://doc.qt.io/qt-5/configure-options.html
  • 使用Qt配置工具编译Qt:https://doc.qt.io/QtForDeviceCreation/qt-configuration-tool.html

2. 依赖安装

2.1. 系统需求

  • Perl (>=5.14)
  • Python (>=2.6.x)
  • A working C++ compiler

2.2. 具体需求

以下内容翻译整理自从 Git 构建 Qt5,此处只列出 Ubuntu/Debian 下的编译依赖。
模块
依赖
备注
SSL
bison,flex,gperf,ruby,libicu
Documentation
clang=>6
build-dep
sudo apt-get build-dep qt5-defaultsudo apt-get install libxcb-xinerama0-dev
Ubuntu21.04 之后,qt5-default 改为 qtbase5-dev;build-dep 需要 src 源支持
build-essentials
sudo apt-get install build-essential perl python git
libxcb
sudo apt-get install ’^libxcb.*-dev’ libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev
尽量选高版本 libxcb
OpenGL support
For Qt Quick 2, a graphics driver with native OpenGL 2.0 support is highly recommended
AccessibilityIt is recommended to build with accessibility enabled, install libatspi 2 and libdbus-1 development packages.
Qt WebKit
sudo apt-get install flex bison gperf libicu-dev libxslt-dev ruby
Qt Webengine
sudo apt-get install libxcursor-dev libxcomposite-dev libxdamage-dev libxrandr-dev libxtst-dev libxss-dev libdbus-1-dev libevent-dev libfontconfig1-dev libcap-dev libpulse-dev libudev-dev libpci-dev libnss3-dev libasound2-dev libegl1-mesa-dev gperf bison nodejs
Qt Multimedia
sudo apt-get install libasound2-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-good1.0-dev libgstreamer-plugins-bad1.0-dev
You’ll need at least alsa-lib (>= 1.0.15) and gstreamer (>=0.10.24) with the base-plugins package
QDoc Documentation Generator Tool
sudo apt install libclang-6.0-dev llvm-6.0

3. 编译配置

以下章节翻译自 Qt 官网文档。
configure 是一个命令行工具,它决定如何为特定平台构建 Qt。 在 Qt 中,configure 能够筛选不需要的功能,决定如何构建应用程序,和部署到主机平台上的方式。本页讨论了一些配置选项,但要查看完整的选项列表,请输入命令 configure -h。 配置应该从主 Qt 源目录运行。
除非另有说明,本页中的命令适用于 Linux 平台。 在 macOS 和 Windows 上,PATH 和目录结构不同,因此命令会有所不同。 此外,在 Windows 系统上,配置脚本称为 configure.bat。运行 configure 后,使用属于所选工具链的 make 工具构建源代码。

3.1. 源码,构建,和安装目录

从源码包或者 git 仓库中,可以获得源码,解压之后进入源码目录。构建目录是那些与构建相关的文件存储的地方,比如 Makefile 文件,object 文件以及其他中间文件。安装文件夹是二进制和库安装的地方,同时也被系统或者应用程序使用。
推荐使用影子构建和使用 -prefix 选项将这些目录分开。这使您能够将 Qt 源代码树与存储在单独目录中的构建工件和二进制文件保持干净。 如果您想从同一源代码树进行多个构建,但针对不同的配置,则此方法非常方便。 要进行影子构建,请从单独的目录运行 configure:
配置 -prefix 选项意味着 Qt 二进制和库会被安装到其他目录,本例是 /usr/local/Qt-5.15.1。运行 qmake,在 ~/qt-build 目录下生成 Makefile 文件。当 Makefile 生成后,运行下面的命令构建 Qt 的二进制和库,并且安装他们。

3.2. 模块和功能

Qt 由不同的模块组成,它们的源代码可以在顶级源代码目录中的不同目录中找到。 用户可以明确排除特定的顶级目录以限制构建时间。 此外,每个 Qt 模块可能具有也可以显式启用或禁用的功能。

3.2.1. 排除 Qt 模块

configure 的 -skip 选项允许从 Qt 构建中排除顶级源目录。 请注意,许多目录包含多个 Qt 模块。 例如,要从 Qt 构建中排除 Qt NFC 和 Qt 蓝牙,请提供 -skip qtconnectivity 作为要配置的参数。
./configure -skip qtconnectivity

3.2.2. 包含或排除功能

选项 -feature- 和选项 -no-feature- 可以包含或者排除特殊的特性。例如,提供 -no-feature-accessibility 选项作为参数,即可禁用Accessibility 功能:
使用 configure -list-features 在命令行上显示所有可用功能的列表。 请注意,功能可能依赖于其他功能,因此禁用某个功能可能会对其他功能产生副作用。
Qt 配置工具是 Qt 5.8 引入的一个图形化配置界面,需要商业授权证书才可以使用,能够更方便的开关功能。

3.3 第三方库

Qt 源代码包包含第三方库。 要设置 Qt 应该使用系统版本的库还是使用捆绑版本,请在要配置的库名称之前传递 -system 或 -qt。
下表总结了第三方选项:
库名称
Qt 绑定
系统已安装
zlib
-qt-zlib
-system-zlib
libjpeg
-qt-libjpeg
-system-libjpeg
libpng
-qt-libpng
-system-libpng
freetype
-qt-freetype
-system-freetype
PCRE
-qt-pcre
-system-pcre
-qt-harfbuzz
-system-harfbuzz
也可以使用 -no 代替 -qt 来禁用对这些库的支持。 例如,要使用系统的 xcb 库并禁用 zlib 支持,请输入以下内容:
如果想查看完整的选项列表,参考帮助命令 configure -help。

3.4. 编译选项

  • platform 选项设置用于构建 Qt 源代码的主机平台和编译器。 支持的平台和编译器的列表可在支持的平台页面中找到,而完整列表可在 qtbase/mkspecs 目录中找到。
例如,在 Ubuntu Linux 系统上,Qt 可以被几种编译器编译,例如 clang 或 g++:
对于 Windows 机器,可以使用 MinGW 或 Visual Studio 工具链来编译 Qt。
之后,生成的 Makefile 将使用适当的编译器命令。

3.5. 跨平台编译选项

要配置 Qt 进行跨平台开发和部署,需要设置目标平台的开发工具链。 此设置因支持的平台而异。
常见的选项有:
  • xplatform - 目标平台。 有效的 xplatform 选项与 qtbase/mkspecs 中的 -platform 选项相同。
  • device - 特定设备或芯片组。 配置兼容的设备列表可在 qtbase/mkspecs/devices 中找到。 有关更多信息,请访问设备 Wiki 页面。
  • device-option - 设置额外的 qmake 变量。 例如,-device-option CROSS_COMPILE=
    • 根据某些设备的需要提供环境变量 CROSS_COMPILE。
注意:非桌面目标的工具链通常带有一个所谓的 sysroot,Qt 需要针对它进行配置。

3.5.1. 平台的特殊选项

以下页面提供了有关如何为特定平台开发配置 Qt 的指南:
  • 设备 - 其他设备和芯片组的列表

3.6. 适用于 Windows 的 OpenGL 选项

在 Windows 上,Qt 可以使用系统 OpenGL 或 ANGLE 进行配置。默认情况下,Qt 配置为使用动态 OpenGL。这意味着它会尝试使用系统 OpenGL 并回退到 ANGLE,它与 Qt 捆绑在一起并依赖于 DirectX SDK,如果原生 OpenGL 不起作用。 ANGLE 支持运行依赖于 OpenGL 的 Qt 应用程序,而无需安装最新的 OpenGL 驱动程序。如果 ANGLE 也失败,Qt 将回退到软件渲染,这是最慢但最安全的渲染方法。
  • opengl 选项可用于将 Qt 配置为在目标系统中使用 OpenGL、不同版本的 OpenGL ES(带或不带 ANGLE),或在可用的 OpenGL 实现之间动态切换。
configure.bat -opengl dynamic
使用动态选项,Qt 将首先尝试使用原生 OpenGL。如果失败,它将回退到 ANGLE,最后在 ANGLE 失败的情况下也将回退到软件渲染。
对于桌面选项,Qt 使用安装在 Windows 上的 OpenGL,要求目标 Windows 机器中的 OpenGL 与应用程序兼容。 -opengl 选项接受两个版本的 OpenGL ES,用于 OpenGL ES 2.0 的 es2 或用于 OpenGL ES Common Profile 的 es1。
您还可以使用 -opengl dynamic,它使应用程序能够在运行时在可用选项之间动态切换。有关使用动态 GL 切换的好处的更多详细信息,请参阅图形驱动程序。

3.7. 开发者构建

构建选项 -developer-build 不是用于承载应用程序,但可用于开发Qt。这样的生成包含比标准生成更多的导出符号,并以更高的警告级别编译。

3.8. 配置方法

4. 遇到的问题

4.1. 无 QPA 平台插件可用配置错误

需要安装 libxcb 并查看系统需求章节,并查看系统是否满足‘系统需求’章节。

4.2. 编译 QWebengine 出现 CPURegList 错误

4.3. “cannot stat file …”配置错误

目前系统中 Perl 版本太低,至少需要 5.14 版本

4.4. Debian 下开启 qdoc 选项配置错误

Debian 允许安装多版本 Clang,LLVM_INSTALL_DIR 应该设置成 /usr/lib/llvm- 路径,而不是 /usr/llvm。

4.5. qmlscene 出现“Cannot create platform GL context”

出现 “Cannot create platform GL context, none of GLX, EGL, DRI2 is enabled”
尝试安装 libx11-xcb-dev 包:
之后需要重新允许 configure 配置,并且强制 qtbase/src/plugins/platforms/xcb 重编译。

4.6. 缺少 ICU 无法编译 WebKit

在配置检查中,已经不在检测是否有 ICU,因此需要
  • 你可以删除/重命名 qtwebkit,qtwebkit-examples-and-demons 目录来跳过 Qt Webkit 编译。
  • 选项 –no-webkit 已经加入,可以查看 QTBUG-20577 issue.

4.7. Qt D-Bus 编译失败

失败信息 “inconsistent user-defined literal suffixes”,发生在使用 GCC 4.7 构建 Qt5,且当前系统 D-Bus < 1.4.2 版本。
错误信息如下:
qdbusinternalfilters.cpp:124:36: error: inconsistent user-defined literal suffixes ‘DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER’ and ‘DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER’ in string literal
此问题已经被上游修复,更换新版或者手动修改头文件。

4.8. isNull is not defined (from qvariant_p.h)

C++ 支持检测,然而当前 GCC 没有支持。可以通过传入 -no-c11 选项来修复。

4.9. cc1: fatal error: .pch/release-shared/QtGui

提示没有那个文件或目录,通过 -no-pch 参数来修复。

4.10. 触摸屏(或者 Wacom 板)不工作

Qt 依赖 XInput 2.2 或者更高版本,XInput 2.0 作为 failback 选项。
尝试再试启动应用,在开始之前会出现如下字样:
如果没有输出 2.2 或者更高的字样,表明头文件在 Qt 构建时不可用;
如果有输出 2.2 或者更高但是没有在最后输出这是一个触摸屏,获取是其他原因导致了触摸屏没有被识别。
如果经验证,其他 X11 应用可用,你可以向 Qt 提交一个 bug。

4.11. 中文字体不显示

添加 -fontconfig 选项,并且只能使用 system-freetype 参数

4.12. 触摸屏支持

添加 -medev 选项

4.13. 未定义 ‘VP8DspInitNEON’

修改qtimageformats/src/3rdparty/libwebp/src/dsp/dsp.h文件,注释掉下面的行:
//#define WEBP_USE_NEON

4.14. openssl 错误

5.10 版本之前需要 libssl1.0 的支持

4.15. qtwebengine 无法启动

根据 Qt 文档描述,在 MacOS 或 Linux (desktop,嵌入式)上,会默认启用沙盒机制,可以通过下列任一方法绕过:
  1. 设置 QTWEBENGINE_DISABLE_SANDBOX 为 1
  1. 在可执行文件后加入 –no-sandbox
  1. 设置 QTWEBENGINE_CHROMIUM_FLAGS 为 –no-sandbox

4.16. 链接 libpng 错误

一般表现为报告 undefined reference to png_xxx 错误。解决办法:
  1. 确定系统 libpng 安装位置
  1. 建立库链接
  1. 修改 Makefile
找到 Makefile 中的 LIBS ,在后面添加 - L/lib/x86_64-linux-gnu -lpng

4.17. qtwebkit 编译失败

QtWebKit 从 5.6 开始被移除,要让后面的库支持编译,需要处理 JSChar 和 UChar 之间转换的问题,网上有相关补丁。

5. 编译示例

6. 参考文档

中年码农的困境log-001-我与计算机