当前位置: 首页 > news >正文

从源码编译完整版Qt:包含QtWebEngine与QDoc的实战指南

1. 项目概述:为什么我们需要自己动手编译一个“完整版”Qt?

如果你正在维护一个使用了QtWebEngine模块的桌面应用,或者你的项目文档需要依赖QDoc来生成,那么你很可能已经遇到了一个头疼的问题:从Qt官方渠道下载的预编译二进制包,无论是离线安装器还是在线安装工具,默认都不包含QtWebEngine和QDoc这两个模块。这绝不是偶然的疏忽,而是因为这两个模块的编译过程极其复杂、耗时漫长,且对系统环境有特殊要求。官方为了提供开箱即用的轻量级体验,默认就把它们“阉割”掉了。

我最近就踩了这个坑。项目需要升级到Qt 5.15.17这个长期支持版本,但我们的应用内嵌了一个基于WebEngine的浏览器组件,用于展示一些动态图表和富文本内容。当我兴冲冲地从官网下载了安装包,配置好项目后,编译器无情地报错:找不到QWebEngineView的头文件。那一刻我才意识到,预编译的“便利”背后,隐藏着功能缺失的代价。对于依赖特定模块的开发者来说,自己动手从源码编译一个“完整版”的Qt,从一项可选的技能变成了必须掌握的生存技能。

自己编译Qt,听起来很吓人,尤其是涉及到Chromium内核的QtWebEngine。网上零散的教程要么年代久远,要么语焉不详,或者只讲了一半。我花了整整一周时间,在Windows和Linux系统上反复试验,踩遍了能踩的坑,终于梳理出了一套稳定、可复现的完整编译流程。这篇文章,就是这份经验的完整记录。它不仅会带你一步步走通编译流程,更会深入解释每个步骤背后的“为什么”,以及那些官方文档里不会写的“坑”在哪里。无论你是为了项目需求,还是想深入学习Qt的构建系统,这篇文章都能给你一个扎实的起点。

2. 编译前的深度准备:环境、源码与工具链的精准配置

编译Qt,尤其是包含QtWebEngine,绝不是简单的configure && make。它更像是一场精密的“外科手术”,术前准备决定了手术的成败。这一步的疏忽,会导致后续编译过程中出现各种光怪陆离的错误,且极难排查。

2.1 系统环境与依赖库的彻底清查

首先,我们必须为编译准备好一个“洁净”且“功能齐全”的操作系统环境。这里的“洁净”不是指新装系统,而是指没有残留的、可能冲突的旧版Qt库或构建工具。“功能齐全”则意味着必须安装所有必要的编译依赖。

对于Linux系统(以Ubuntu 20.04/22.04为例):这是编译体验相对较好的平台。你需要安装一长串的开发库。打开终端,执行以下命令来安装基础编译工具和核心依赖:

sudo apt update sudo apt install build-essential libgl1-mesa-dev libglu1-mesa-dev -y

接下来是QtWebEngine的重度依赖,它基于Chromium,因此需要Chromium构建所需的各种库:

sudo apt install bison flex gperf libnss3-dev libdbus-1-dev libfontconfig1-dev libx11-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libx11-xcb-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev -y

此外,还需要音频、视频、网络等多媒体支持库:

sudo apt install libasound2-dev libpulse-dev libssl-dev libicu-dev libavcodec-dev libavformat-dev libswscale-dev libevent-dev libminizip-dev libre2-dev libsnappy-dev libwebp-dev libopus-dev libvpx-dev libxml2-dev libxslt1-dev liblcms2-dev libopenjp2-7-dev -y

注意:以上列表看起来冗长,但缺一不可。例如,缺少libwebp-dev可能导致WebP图片支持编译失败;缺少libre2-dev(Google的正则表达式库)会直接导致QtWebEngine配置阶段报错。建议一次性安装完毕,避免后续因依赖问题中断编译。

对于Windows系统:Windows下的编译环境搭建更为复杂,因为缺乏统一的包管理器。官方推荐使用MSVC编译器套件。你需要:

  1. 安装Visual Studio 2019或2022:社区版即可。安装时,务必在“工作负载”中勾选“使用C++的桌面开发”,并在右侧的“安装详细信息”中,确保选中了“MSVC v142 - VS 2019 C++ x64/x86 生成工具”和“Windows 10 SDK”(或Windows 11 SDK)。这是编译器的核心。
  2. 安装Python:Qt构建系统大量使用Python脚本。从Python官网安装3.7以上版本(如3.9),安装时务必勾选“Add Python to PATH”,将Python添加到系统环境变量。
  3. 安装Perl:用于处理一些自动化脚本,可以从Strawberry Perl或ActiveState Perl官网下载安装。
  4. 安装Git:用于获取子模块源码,特别是QtWebEngine的Chromium代码。

2.2 源码获取:不仅仅是下载一个压缩包

Qt的源码管理采用了Git子模块(Submodule)的方式,这意味着主仓库只包含框架代码,像QtWebEngine这样的模块,其庞大的Chromium代码是以子模块形式链接的。如果你直接下载官网的.tar.xz源码包,通常不包含子模块代码,或者包含的是过时的快照,这会导致编译失败。

正确的方法是使用Git:

git clone https://code.qt.io/qt/qt5.git cd qt5 git checkout v5.15.17-lts-lgpl # 切换到5.15.17的LTS标签

接下来是关键一步:初始化并更新子模块。由于QtWebEngine的子模块非常庞大(超过10GB),直接更新会非常慢且可能失败。这里需要一个技巧:使用--depth 1参数进行浅克隆,只获取最新的一次提交,可以极大减少下载量。

perl init-repository --module-subset=qtbase,qtwebengine,qtdoc

这里我使用了--module-subset参数,只初始化我们关心的核心模块(qtbase)、目标模块(qtwebengine, qtdoc)及其直接依赖。这比初始化全部模块要快得多。执行此命令后,脚本会自动克隆所需的子模块仓库。

实操心得:网络是这一步骤最大的敌人。由于需要从code.qt.iochromium.googlesource.com等地址拉取代码,国内环境可能会非常缓慢甚至超时。建议配置可靠的网络环境,或者寻找包含子模块的国内镜像源码包。如果init-repository中途失败,可以进入对应的子模块目录(如qtwebengine/src/3rdparty),手动执行git fetchgit checkout来补救。

2.3 编译目录的规划:构建与源码分离

这是一个重要的最佳实践:不要在源码目录内直接进行编译(in-source build)。应该创建一个独立的构建目录(out-of-source build)。这样做的好处是保持源码目录的纯净,你可以随时删除构建目录重新开始,或者针对不同的配置(如Debug/Release,不同编译器)创建多个构建目录而互不干扰。

假设你的源码目录是/home/user/qt-src,你可以这样操作:

mkdir /home/user/qt-build cd /home/user/qt-build

后续所有的配置(configure)和编译(make)命令,都在这个qt-build目录下执行,而configure脚本则指向源码目录的路径。

3. 配置阶段详解:理解每一个参数的意义

进入我们创建的构建目录,现在开始最关键的一步:配置。configure脚本会根据你的参数,生成适合你平台的Makefile。参数的选择直接影响编译的模块、功能以及最终库的形态。

一个针对Linux系统,包含QtWebEngine和QDoc的典型配置命令如下:

../qt-src/configure -prefix /opt/Qt5.15.17-full \ -opensource \ -confirm-license \ -release \ -optimize-size \ -nomake examples \ -nomake tests \ -skip qtvirtualkeyboard \ -webengine-proprietary-codecs \ -webengine-icu \ -webengine-ffmpeg \ -ssl \ -opengl desktop

让我们拆解每一个参数:

  • -prefix /opt/Qt5.15.17-full:指定编译后Qt的安装路径。编译完成后,执行make install会将所有库、头文件、工具安装到这个目录。请确保你有该目录的写入权限(通常需要sudo),或者换成一个你有权限的路径,如$HOME/Qt5.15.17
  • -opensource-confirm-license:声明使用开源协议并自动确认许可。
  • -release:编译发布版本。如果你需要调试符号,可以换成-debug-debug-and-release,但这会显著增加编译时间和磁盘占用,尤其是对于庞大的QtWebEngine。
  • -optimize-size:进行尺寸优化。对于发布版本是个好选择。
  • -nomake examples-nomake tests:不编译示例和测试程序。这能节省大量时间。除非你需要参考示例,否则建议加上。
  • -skip qtvirtualkeyboard:跳过虚拟键盘模块。这是一个可选模块,如果你不需要可以跳过以加快编译。
  • -webengine-proprietary-codecs关键参数。启用对H.264、AAC等专利编解码器的支持。没有这个参数,你的QtWebEngine将无法播放绝大多数在线视频(如MP4格式)。启用它可能需要你自行承担潜在的专利许可风险(在商业应用中需注意)。
  • -webengine-icu-webengine-ffmpeg:启用ICU(Unicode支持)和FFmpeg(多媒体处理)支持。对于完整的Web功能是必须的。
  • -ssl:启用SSL/TLS支持,使网络访问和WebEngine能打开HTTPS网站。
  • -opengl desktop:使用系统原生的OpenGL库。在Linux上通常这样指定。

对于Windows平台(在x64 Native Tools Command Prompt for VS 2019/2022中运行),配置命令类似,但有一些平台特定项:

..\qt-src\configure -prefix C:\Qt\5.15.17-full ^ -opensource ^ -confirm-license ^ -release ^ -platform win32-msvc ^ -mp ^ -nomake examples ^ -nomake tests ^ -skip qtvirtualkeyboard ^ -webengine-proprietary-codecs ^ -webengine-icu ^ -webengine-ffmpeg ^ -ssl ^ -opengl desktop

区别在于:

  • -platform win32-msvc:指定使用MSVC平台工具链。
  • -mp:启用多进程编译,充分利用多核CPU。

执行configure脚本后,它会花几分钟时间检测你的系统环境、检查依赖,并最终输出一个配置摘要。请务必仔细阅读这个摘要!它会明确告诉你哪些特性被启用(yes),哪些被禁用(no),原因是什么。重点关注以下几行:

  • Qt WebEngine .......................... yes
  • Qt WebEngine Proprietary Codecs ........ yes(如果你指定了)
  • Qt Documentation Tools (QDoc) .......... yes

如果这里显示no,说明配置失败,你需要根据上面的提示信息(通常是缺少某个开发库)去解决依赖问题,然后重新运行configure

4. 编译与安装:一场对耐心和硬件的考验

配置成功后,就可以开始编译了。这将是整个过程中最耗时的一步,尤其是QtWebEngine模块。

4.1 核心编译流程与资源管理

在构建目录下,执行编译命令。强烈建议使用-j参数来指定并行编译的作业数,这能极大缩短时间。作业数通常设置为你的CPU核心数或核心数+1。

对于Linux:

make -j$(nproc)

$(nproc)命令会自动获取你的CPU核心数。

对于Windows(在刚才的命令行中):

nmake

MSVC的nmake本身不支持-j参数,但我们在configure时已经加了-mp,它内部会进行并行优化。

编译过程可能持续数小时,具体取决于你的CPU性能、内存大小和磁盘速度(尤其是IO性能)。QtWebEngine的编译会占用大量内存(建议16GB以上)和磁盘空间(整个构建目录可能膨胀到30-40GB)。

注意事项:编译过程中,请确保系统有足够的剩余内存和磁盘空间。如果内存不足,编译进程可能会被系统杀死(出现Killedexit code 137错误)。如果磁盘空间不足,编译会失败并报错。建议在开始前,至少保证有50GB的可用磁盘空间。

4.2 安装与环境配置

编译成功后(没有报错地结束),就可以进行安装了:

# Linux 下可能需要sudo,取决于-prefix路径 sudo make install # Windows 下 nmake install

安装过程会将编译好的所有库、可执行文件(如qmake、QDoc)、头文件、插件等,复制到configure时指定的-prefix目录下。

安装完成后,你需要配置你的开发环境来使用这个新编译的Qt版本。

  1. 配置Qt Creator:打开Qt Creator,进入工具->选项->Kits->Qt Versions,点击“添加”,然后浏览到你的安装目录(如/opt/Qt5.15.17-fullC:\Qt\5.15.17-full),选择其中的bin/qmake可执行文件。添加成功后,在Kits标签页中,为你已有的Kit选择这个新添加的Qt版本即可。
  2. 命令行使用:如果你想在命令行中使用这个Qt,需要设置环境变量。在Linux的~/.bashrc或Windows的系统环境变量中,将QTDIR设置为你的安装路径,并将$QTDIR/bin(Linux)或%QTDIR%\bin(Windows)添加到PATH环境变量中。

4.3 验证编译成果

安装和配置完成后,必须进行验证。

验证QtWebEngine:创建一个最简单的测试程序:

// main.cpp #include <QApplication> #include <QWebEngineView> int main(int argc, char *argv[]) { QApplication app(argc, argv); QWebEngineView view; view.setUrl(QUrl("https://www.qt.io")); view.show(); return app.exec(); }

用你新编译的Qt Kit来编译运行这个程序。如果能看到Qt官网页面正常加载,说明QtWebEngine编译成功且工作正常。

验证QDoc:QDoc是用于从源码注释生成文档的工具。安装后,它位于安装目录/bin/qdoc。你可以在命令行中运行qdoc --version来检查是否可用。更进一步的验证,可以尝试用它编译一个简单的.qdocconf配置文件来为你的项目生成文档。

5. 疑难杂症与深度排错指南

自己编译Qt,尤其是包含QtWebEngine,遇到问题是常态。下面是我在多次编译中遇到的典型问题及其解决方案。

5.1 编译过程中的常见错误与解决

问题一:编译QtWebEngine时,卡在“Running ninja...”或“Submodule ‘src/3rdparty’ is outdated”

  • 现象:编译进程长时间无响应,或直接报错子模块过时。
  • 原因:QtWebEngine的Chromium代码子模块没有正确初始化或更新。
  • 解决
    1. 确保之前用init-repository正确初始化了子模块。
    2. 进入qtwebengine源码目录,手动同步子模块:
      cd /path/to/qt-src/qtwebengine git submodule sync git submodule update --init --recursive --depth 1
    3. 如果网络问题严重,可以考虑寻找包含完整子模块的国内镜像源码包。

问题二:编译时报错,提示缺少libxxx-devxxx.h: No such file or directory

  • 现象:编译中断,错误信息明确指出缺少某个头文件或库。
  • 原因:系统缺少必要的开发依赖包。
  • 解决:这是Linux编译中最常见的问题。根据错误信息中的库名或头文件名,使用apt searchapt-file search命令查找对应的开发包并安装。例如,错误提示libwebp/libwebp.h找不到,那就安装libwebp-dev。这就是为什么在准备阶段强调要安装全依赖。

问题三:内存不足(OOM Killer)导致编译进程被杀死

  • 现象:编译过程中,终端突然显示Killed,或者make进程以错误代码137退出。
  • 原因:系统物理内存和交换空间(swap)不足,Linux内核的OOM Killer终止了最耗内存的进程(通常是编译QtWebEngine的clang++或链接器)。
  • 解决
    1. 临时方案:减少并行编译作业数。将make -j$(nproc)改为make -j2make -j1,虽然慢,但能大幅降低内存峰值。
    2. 根本方案:增加交换空间。如果是在虚拟机或云服务器上编译,务必分配足够的内存(建议16GB+)和交换空间(8GB-16GB)。
      # 创建一个8GB的交换文件 sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile # 使其永久生效,编辑/etc/fstab,添加:/swapfile none swap sw 0 0

问题四:Windows下编译QtWebEngine时,ninja报错“unsupported GNU version! gcc versions later than 8 are not supported!”

  • 现象:在Windows上使用MSVC编译,但QtWebEngine的Chromium部分在调用某些工具时遇到了系统中安装的MinGW或Cygwin的gcc版本过高。
  • 原因:Chromium的某些工具链脚本对GCC版本有特定限制,而你PATH环境变量中可能存在新版的GCC(例如,如果你安装了MinGW-w64或Cygwin)。
  • 解决
    1. 临时从PATH中移除包含高版本GCC的路径(如MinGW、Cygwin的bin目录)。
    2. 或者,尝试安装一个较旧版本的GCC(如7.x或8.x),并将其路径放在PATH的前面。但这在Windows上比较麻烦。
    3. 更推荐的方法:使用“x64 Native Tools Command Prompt for VS”进行编译,这个环境默认配置了纯净的MSVC工具链,不会混入GCC。确保在这个命令行中,where gcc命令找不到任何结果。

5.2 配置参数导致的特性缺失

问题:编译出的程序无法播放MP4视频

  • 原因:在configure时没有添加-webengine-proprietary-codecs参数。
  • 解决没有补救办法,必须重新配置和编译。这就是为什么在配置阶段要反复确认摘要信息。如果你不确定是否需要某个功能,特别是-webengine-proprietary-codecs-webengine-ffmpeg,建议先加上。重新编译的代价是巨大的。

5.3 安装后运行时的问题

问题:程序运行时找不到QtWebEngine相关的插件或资源

  • 现象:程序能启动,但Web页面空白,或控制台输出找不到qtwebengine_resources.pak等文件。
  • 原因:Qt的插件和资源文件没有被正确部署。make install有时可能不会复制所有必要的运行时文件,或者你的程序没有在正确的路径下寻找它们。
  • 解决
    1. 检查安装目录下是否存在plugins/platforms,plugins/printsupport,resources等目录及其中的文件。
    2. 对于开发阶段,在Qt Creator中运行,环境通常会自动设置好。对于独立发布的应用,你需要使用windeployqt(Windows)或类似的部署工具来收集所有依赖库和资源文件。确保部署工具调用的是你新编译的Qt版本对应的那个。
    3. 手动将安装目录下的libQt5WebEngineCore.so.5(Linux)或Qt5WebEngineCore.dll(Windows)及其依赖、以及resources目录复制到你的可执行文件同级目录下。

6. 编译后的优化与定制思考

成功编译并验证后,你获得的是一个完全符合你需求的Qt SDK。但这并不是终点,这里还有一些进阶的思考方向。

1. 调试符号与发布版本的权衡:我们之前用的是-release配置。如果你需要调试Qt框架本身的代码(比如追踪一个QtWebEngine的内部崩溃),你需要编译一个带有调试符号的版本。可以使用-debug-debug-and-release。但请注意,带有调试信息的QtWebEngine库文件大小会膨胀数倍,编译时间也会更长。一个折中的方案是,只编译你关心的模块(如qtbase和qtwebengine)的调试版本,其他模块用发布版本。这需要对Qt的模块化编译有更深的理解,可以通过在configure后,单独进入qtbaseqtwebengine目录进行make sub-src(仅编译该模块)来实现,但模块间的依赖需要妥善处理,对新手不友好。

2. 模块化裁剪:Qt是一个庞大的框架,你的项目可能只用到了其中一小部分。通过configure的-skip参数,你可以跳过那些你永远用不到的模块(如Qt3D, QtBluetooth, QtNfc等),这能显著减少编译时间和最终安装包的大小。研究一下configure -help的输出,了解所有可用的模块,根据你的项目需求进行精细化的裁剪。

3. 交叉编译:本文主要聚焦于本地编译(为当前使用的机器编译)。但在嵌入式开发中,你需要为ARM等不同架构的硬件编译Qt。这就需要配置交叉编译工具链(通过-xplatform参数指定)。交叉编译QtWebEngine是另一个层次的挑战,因为它涉及为目标架构编译整个Chromium,对工具链和环境的要求极为苛刻。通常,嵌入式平台会使用更轻量级的浏览器引擎(如基于WebKit的QtWebKit,但Qt 5.15后官方已不维护)或者直接使用系统提供的Web视图。

4. 持续集成(CI)自动化:对于团队项目,将Qt的编译流程脚本化并集成到CI/CD管道中(如GitLab CI, Jenkins),可以确保所有开发者使用完全一致的Qt环境,避免“在我机器上是好的”这类问题。你需要将环境准备、源码获取、配置、编译、安装打包等一系列步骤写成脚本。关键是要处理好依赖安装和缓存(如编译好的第三方库),以缩短CI的运行时间。

我个人在实际操作中的体会是,第一次完整编译Qt5.15.17 with WebEngine,更像是一次“洗礼”。它迫使你去理解构建系统的运作、去解决复杂的依赖、去耐心等待漫长的编译过程。但一旦成功,你获得的不仅仅是一个可用的Qt库,更是一种对底层构建链的掌控感和解决问题的信心。以后遇到任何与Qt环境相关的问题,你都不会再感到畏惧,因为你知道如何从源码开始,构建一个完全属于自己的、稳固的基础。

http://www.jsqmd.com/news/1177726/

相关文章:

  • PyInstaller 与 Nuitka 打包 EXE 逆向对比:2 种工具源码保护强度实测
  • Ubuntu下PlatformIO下载极慢?一招配置proxy,完美解决ESP32依赖包下载超时!
  • 用原生 JavaScript 实现一个基础代谢率(BMR)在线计算器:从公式到落地
  • 2.算法效率的核心密码:时间复杂度和空间复杂度详解
  • NestOS官网源代码解析:构建现代化容器主机操作系统网站的技术实践
  • 江诗丹顿官方换电池价格查询|热线及完整维修地址权威信息公告(2026年7月最新) - 江诗丹顿服务中心
  • Java Web人事管理系统实战:JSP+Servlet+MVC架构完整开发指南
  • 英伟达出手:通用机器人为何总在现实中「翻车」?
  • Nacos 2.3.2 Windows 单机部署:3步配置MySQL持久化与鉴权启动
  • openEuler hygon-kernel深度解析:国产海光处理器内核优化完全指南
  • GCC16倒逼C++生态升级:分层兼容架构与项目迁移实战
  • WeChat 与微信数据导出对比:2版本差异解析,通讯录等5类数据仅限海外版
  • OpenAI创始人奥尔特曼:至少到目前为止,我相当确信,AI总体上是在创造就业岗位
  • 影刀RPA 变量使用进阶:list-dict-自定义对象
  • 导师说论文有AI痕迹,有哪些真正亲测好用的的降AIGC软件推荐?
  • 高精度信号采集系统设计与优化:AD7175-8与TM4C129EKCPDT应用
  • 2026萍乡漏水检测维修口碑榜TOP5权威推荐:正规防水补漏公司甄选-卫生间/厨房/阳台/屋顶/地下室渗漏水精准查漏:房屋防水补漏避坑指南 - 安佳防水
  • NoteExpress 3.8 文献管理实战:10篇SCI论文的引用格式自动生成与3步定稿流程
  • LLM投毒攻击原理与防御:数据层后门的精准建模
  • OpenGauss内置函数初始化与查询全解析
  • 终极指南:SMAPI如何成为星露谷物语模组生态的基石
  • 实验报告
  • AI编程智能体在结构软件开发中的实践应用与优化策略
  • 字符串输入校验:只允许中英文数字与基础符号
  • 模板驱动型文档自动化:让非技术人员用规则代替编码
  • python神经网络编程入门(八)——全连接网络的“死穴“—— 为什么图像任务必须换思路,CNN?
  • 突破光学极限!新型“拼接”超透镜打破高NA与大视场魔咒
  • 真力时官方服务项目及价格查询|完整地址与24小时售后热线权威信息公告(2026年7月最新) - 亨得利官方服务中心
  • Winhance:开源免费的Windows系统优化工具使用指南
  • C++单元测试实战:gtest与gmock环境搭建、核心用法与工程实践