Ubuntu 20.04 x86_64源码编译Qt 5.15.2完整指南
简介面向需要在 Ubuntu 20.04 x86 环境搭建 Qt 5.15.2 定制编译链的开发者这份源码包提供了完整的 Qt 5.15.2 头文件集合。包内共 2000 个 h 文件压缩后约 50.14MB涵盖 QtCore、QtGui、QtWidgets、QtNetwork 等模块的公共接口与内部数据结构声明可用于源码级调试、API 检索或作为交叉编译时的系统头文件参考。目前已有 99 人学习适合希望深入理解 Qt 5.15.2 内部实现、解决编译期符号缺失问题或进行二次开发的用户。借助这份头文件树开发者可更快定位模块依赖关系结合官方文档完成 configure 与 make 流程并针对自身项目裁剪不必要的模块在配置阶段灵活指定模块开关也能有效压缩生成库的体积提升后续开发效率。 2023年的时候项目组有一个跨平台组件的活儿要求目标环境是Ubuntu 20.04x86_64架构界面层必须锁定Qt 5.15.2。当时第一反应是直接上apt但Ubuntu 20.04官方源里Qt版本停在5.12远远满足不了需求。在线安装器又是图形界面对服务器部署和内网环境十分不友好最后只能老老实实下载源码包自己编译。这个“5.15.2 Linux x86环境下的源码包Ubuntu 20.04下编译”就是我当时的实际需求。当时踩了不少坑也积累了一套可复用的流程这篇就把整个思路和实操细节整理出来。不管你是做嵌入式交叉编译还是在做国产化适配又或者是在内网环境里搭建Qt开发环境这篇文章都适用。我会把从依赖准备、configure参数选择、make编译到环境变量配置的完整路径走一遍重点解释每个关键步骤背后的原因顺便把我踩过的坑列出来方便你少走弯路。1. 为什么费劲编译Qt源码而不是直接用现成方案1.1 三种获取Qt 5.15.2的方式对比在Linux下装Qt常见路子无非三条apt安装、官方在线安装器、源码编译。我挨个试过差别非常大。获取方式优点缺点适用场景apt install qt5-default命令简单、依赖自动处理版本通常老一截20.04源里是5.12不挑版本、纯学习用途官方在线安装器版本全面可选组件多图形化交互需要桌面环境、有网络认证流程内网基本走不通离线包体积大个人开发机联网方便源码编译版本精确控制、可裁剪模块、可定制configure参数、离线友好编译耗时长依赖处理繁琐出错排查成本高生产环境、内网部署、国产化适配、嵌入式相关我这次选源码编译核心原因是目标服务器在内网在线安装器完全走不通。而且项目里不依赖WebEngine这种重型模块源码编译能直接skip掉最终装出来的Qt体积比在线安装器默认的小很多。1.2 为什么锁定5.15.2这个版本5.15.2这个版本号在当前Qt生态里依然很特殊。它是Qt 5系列的LTS版本官方承诺长期维护修复了一些已知的稳定性和安全问题稳定性比5.12和纯5.15.0都更让人放心。很多商业项目、工业软件、教学系统都锁定这个版本网上相关的资料和经验积累也最厚遇到问题容易找到解决方案。当然6.0出来之后5.15.2已经不是一个“新”版本了但恰恰因为新版本API变动大大量存量项目反而积压在5.15.2上。做适配、做国产化替代的时候目标平台经常指定这个版本。从源码编译这个角度切入能够完全绕开在线认证、账号绑定这些环节在合规性上也更让人放心。2. 编译环境的准备和依赖处理2.1 确认系统架构和环境基线动手之前先确认系统基础信息。我在Ubuntu 20.04.6 LTS上操作内核是5.15系列的generic内核。确认架构是x86_64而不是ARM或ARM64这决定了后面configure参数里指定的xcb、platform插件等编译特性。uname -a # Linux hostname 5.15.0-91-generic #101-Ubuntu SMP x86_64 GNU/Linux cat /etc/os-release # 确认是Ubuntu 20.04.6 LTSx86_64架构下Qt默认会启用xcb平台插件作为X11环境的支撑这也是绝大多数Linux桌面应用运行的基石。如果这一步架构不对后面很多依赖库的选择都会出问题。2.2 编译工具链和依赖库安装源码编译Qt 5.15.2最基础的是GCC工具链和make工具然后是一大堆跟图形显示、OpenGL、X11协议相关的开发库。我把实际用到的apt安装命令整理成了下面这一组直接整段粘贴执行即可# 基础编译工具 sudo apt update sudo apt install -y build-essential perl python3 # X11与OpenGL相关开发库非常重要 sudo apt install -y libgl1-mesa-dev libglu1-mesa-dev mesa-common-dev sudo apt install -y libegl1-mesa-dev libgles2-mesa-dev # xcb相关依赖缺少会直接导致编译出来的Qt无法在X11桌面下运行 sudo apt install -y libxkbcommon-x11-dev libxcb-xinerama0-dev libxcb-xkb-dev sudo apt install -y libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-render-util0-dev libxcb-shape0-dev # 字体和输入法相关不做中文桌面开发可以视情况跳过 sudo apt install -y libfontconfig1-dev libfreetype6-dev我之所以把xcb相关依赖单独强调是因为哪怕configure阶段没有报错等编译完qmake之后测试Qt程序时仍然可能报找不到xcb平台插件。那个问题排查起来非常绕根源往往就是漏了某一两个libxcb开头的开发包。2.3 磁盘空间、CPU核数和Swap建议Qt 5.15.2源码解压后体积大概在5GB到6GB之间编译中间产物会再占一部分空间建议提前确保/opt或源码所在目录至少有30GB可用空间。我是放在/home/qt-src下面的因为home分区比较大后面make install也不担心爆掉。编译时推荐用多核并行命令是make -jNN一般为物理核数乘以2。我机器是6核12线程实测下来用-j12编译整个流程耗时约1小时40分钟。如果核数少比如双核老机器编译时间可能拉长到5-6个小时要有心理准备。内存不足也是常见问题特别是同时跑多个编译任务时。如果物理内存只有8GB建议加大swap避免编译过程中内存耗尽导致进程被kill。有个简单粗暴的方案就是临时创建一个swap文件sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile编译完成后如果不想保留这8G的swap直接sudo swapoff /swapfile再删文件就行。3. 源码获取与configure核心参数配置3.1 下载对应架构的源码包并校验Qt官方源码包命名一般类似qt-everywhere-opensource-src-5.15.2.tar.xz。这个包在不同架构的机器上都可以用因为它就是一套源码最终编译出来的二进制是和平台相关的这正好也呼应了“x86环境下的源码包”这个说法——架构限制在编译阶段体现而不是下载阶段。我这里是提前在能联网的机器上下载好通过U盘拷贝到内网机器的。建议下载完成后顺手做一下SHA256校验确认文件完整。官方提供的校验值一般是记录在下载页面的对应patch文件里可以和本地计算出来的摘要对比一下sha256sum qt-everywhere-opensource-src-5.15.2.tar.xz3.2 解压并进入源码目录解压时间大约小几十秒tar.xz格式的压缩率比较高解压之后目录名和包名保持一致。tar -xvf qt-everywhere-opensource-src-5.15.2.tar.xz cd qt-everywhere-opensource-src-5.15.2/进入源码根目录后目录里通常有configure、README、qtbase等顶层文件夹一眼就能确认源码包结构完整。3.3 configure参数的含义与选择逻辑代码是通用的但编译选项是决定最终产物形态的关键。我第一次编译时比较保守想着尽量多编一点模块结果在qtwebengine那里卡了整整一下午各种Python环境和Ninja的问题层出不穷。后面第二次编译直接看开了把用不到的模块全部skip掉整个世界清净了所以我最推荐的configure参数如下./configure -prefix /opt/Qt5.15.2 \ -opensource -confirm-license \ -release -shared \ -xcb -qt-xcb \ -qt-libpng -qt-libjpeg \ -no-openssl \ -skip qtwebengine \ -skip qtgamepad \ -skip qtdoc \ -nomake examples -nomake tests \ -fontconfig我逐个解释一下关键参数的含义因为configure选错后面编译出问题再回头改成本很高。-prefix /opt/Qt5.15.2指定安装路径。有这个参数make install才会把编译好的内容整齐地放到这个目录。没指定的话默认会装到/usr/local/Qt-5.15.2虽然能用但路径不够直观。-opensource -confirm-license以开源模式编译并确认LGPL协议自动化编译时必须有不然configure会交互式卡住。-release -shared编译release版本并生成动态库。嵌入式场景如果需要静态库可以改成-static但桌面应用默认用shared更合理方便后续升级补丁。-xcb -qt-xcb使用xcb平台插件。xcb是X11的C接口绑定如果不加这个选项编译出来的Qt在纯X11环境下可能无法创建窗口。-qt-libpng -qt-libjpeg使用Qt自带的png、jpeg解码库。这样可以减少对外部系统库的依赖内网部署场景更省心。-no-openssl因为目标环境不涉及HTTPS网络请求这里先关掉openssl支持。注意如果后续项目里要访问HTTPS接口比如QNetworkAccessManager请求https地址必须把这个参数去掉并安装libssl-dev来启用openssl否则运行时会有SSL错误。-skip qtwebengine跳过WebEngine模块。这个模块依赖Ninja、Python、ICU、FFmpeg一堆东西编译时间非常长动不动3小时起步而且特别容易因为版本不匹配报错。纯桌面应用完全没必要碰它。-skip qtgamepad -skip qtdoc分别跳过游戏手柄模块和文档模块进一步减少编译体积。-nomake examples -nomake tests不生成示例和测试节省编译时间。-fontconfig启用字体配置支持。这个也是把双刃剑启用后中文字体显示更正常但依赖libfontconfig1-dev前面已经装过了。3.4 configure成功标志和常见中途退出configure执行时间一般在10到20分钟之间中间会打印很多检测信息最后如果看到类似“Qt is now configured for building”的提示就说明配置成功可以继续make了。如果中途报错一般是缺少依赖库注意看红色error字样的上一两行那里会直接提示找不到哪个头文件然后用apt补装对应-dev包即可。补充一点configure阶段生成的config.summary文件记录了这次编译的关键特性摘要。比如OpenGL是Desktop版本还是软件渲染版本xcb是否启用这些在后续排查运行问题时非常有用。4. 编译、安装与环境变量配置实操全过程4.1 make -j并行编译与体积控制configure完成后直接敲make开始编译。这里我强烈建议用-j参数编译速度差别非常大。我用的命令是make -j$(nproc)nproc这个命令会直接输出当前机器的CPU线程数配合起来很方便。整个编译过程会比较久建议用tmux或者nohup挂着防止SSH断开导致编译中断。我当时看到的主要编译输出集中在qtbase、qtdeclarative、qtquickcontrols等模块整个过程中有一两处warning但都正常通过。还有一点值得提Qt源码编译过程中会产生大量临时目标文件主要集中在每个模块的build目录下。如果磁盘空间比较紧张编译完成后可以把源码目录整个删掉只保留/opt/Qt5.15.2这个安装目录即可。源码包和中间文件删掉后整个占用会从30GB降到3GB左右。4.2 make install与安装目录结构检查编译完成后进行安装sudo make install安装过程相对快大概几分钟。装完后检查一下/opt/Qt5.15.2目录bin、lib、include、plugins都是标配这几个子目录后面都会用到bin目录放着qmake、moc、uic等工具lib目录放着libQt5Core.so.5.15.2等动态库include目录是头文件plugins/platforms目录下面是libqxcb.so这个平台插件在运行Qt程序时必须有4.3 环境变量设置和qmake自检编译安装完不等于可以直接使用还需要让系统找到这套Qt。环境变量是最关键的一环。需要设置三个变量export PATH/opt/Qt5.15.2/bin:$PATH export LD_LIBRARY_PATH/opt/Qt5.15.2/lib:$LD_LIBRARY_PATH export QT_PLUGIN_PATH/opt/Qt5.15.2/plugins:$QT_PLUGIN_PATHPATH让qmake命令直接可用LD_LIBRARY_PATH让动态链接器能找到Qt动态库QT_PLUGIN_PATH让Qt运行时能找到平台插件如果不想每次开终端都手动设一遍可以把这三行追加到~/.bashrc中之后source ~/.bashrc即可。注意如果系统里同时存在apt装的Qt和源码编译的Qt这样做会优先使用源码版因为PATH顺序在前。设置完之后验证一下qmake -v # QMake version 3.1 # Using Qt version 5.15.2 in /opt/Qt5.15.2/lib看到版本号和路径都正确说明Qt环境已经就位了。4.4 写一个最小的窗口程序验证可用性只看到qmake -v还不够最好实际编译运行一个小程序确认图形环境也没问题。我在/tmp下面建了一个测试目录写了最简单的Qt Widgets程序mkdir -p /tmp/qttest cd /tmp/qttest cat main.cpp EOF #include QApplication #include QLabel int main(int argc, char *argv[]) { QApplication app(argc, argv); QLabel label(Qt 5.15.2 xcb works); label.resize(280, 120); label.show(); return app.exec(); } EOF qmake -project qmake make ./qttest程序窗口能弹出来说明xcb平台插件、GL库、字体配置等环节都是通的。这一步至关重要很多编译本身成功但运行环境有问题的坑都会在这儿暴露。5. 常见问题与排查技巧实录5.1 configure时报错找不到GL/gl.h或EGL相关头文件这个错误比较经典出现的原因是系统缺少OpenGL开发头文件库。Qt的GUI模块在编译时依赖OpenGL。解决办法很直接sudo apt install -y libgl1-mesa-dev mesa-common-dev如果还报EGL相关错误再补装sudo apt install -y libegl1-mesa-dev libgles2-mesa-dev装完后重新运行configure即可不需要从零解压源码。5.2 编译过程中内存耗尽或者卡死常见场景是在编译qtwebengine时出现的这个模块编译时对CPU和内存的占用都比较夸张。如果不想step掉这个模块建议调低并行度比如从-j12改到-j4并且在编译前确认swap空间足够。但如果真的只是做传统桌面应用我建议直接在configure时加上-skip qtwebengine。这样最省心。5.3 运行Qt程序报错could not find or load the Qt platform plugin xcb这个错误可以说是在Linux下手工编译Qt后遇到次数最多的问题。运行编译好的程序时提示找不到xcb插件但实际上/opt/Qt5.15.2/plugins/platforms目录下明明有libqxcb.so。这个问题的根源在于运行时无法定位插件路径或者加载libqxcb.so时连锁缺少了其他依赖库。处理方法分两步走。第一步确保设置好QT_PLUGIN_PATH环境变量指向plugins目录第二步用ldd检查libqxcb.so的依赖库是否有找不到的ldd /opt/Qt5.15.2/plugins/platforms/libqxcb.so | grep not found如果有not found的输出就说明系统缺少某个运行库。比如没有安装libxcb-xinerama0-dev等就会导致libqxcb.so加载失败。用apt装齐后再运行程序就正常了。这里还有一个隐蔽的坑如果系统中已经有一份通过apt安装的Qt并且LD_LIBRARY_PATH一不小心指到了旧版本动态库那么也会报各种莫名其妙的版本冲突。排查时用ldd查看程序依赖的具体路径确认指向的是不是/opt/Qt5.15.2/lib下的库。5.4 编译出来的程序在其他Linux机器上不能运行这是一个很现实的部署问题。源码编译出来的Qt动态库一般依赖当前系统的glibc版本和部分库。如果目标机器是比Ubuntu 20.04更老的系统比如16.04那么glibc版本过低运行时会报GLIBC_2.XX not found。解决办法有两个方向一个是在目标机器上一并使用Qt源码编译并安装保持编译环境一致另一个是尽量采用静态编译configure加-static这样虽然库体积大不少但省去了大量动态库依赖的麻烦。5.5 无法输入中文如果程序编译运行正常但中文输入法用不了通常是输入法框架配置问题。在configure时Qt会检测系统的ibus或fcitx。如果需要中文输入建议在configure前先安装ibus开发相关的依赖否则编译出来的Qt默认不启用ibus插件。Ubuntu 20.04下装sudo apt install -y libibus-1.0-dev装完再重新编译qtbase模块中文输入法一般就能工作了。5.6 关于国产系统和信创环境的适配经验聊到“linux国产”其实我的这套流程在相关场景里也很能打。国产操作系统比如基于Debian/Ubuntu衍生的一些发行版在x86_64架构下内核和glibc版本跟Ubuntu 20.04都比较接近源码编译Qt 5.15.2的步骤几乎可以平移过去。最关键的就是把依赖库装齐然后configure时注意和系统自带的Qt区分开建议把前缀设为独立的目录避免污染系统库。另外要注意这类系统默认可能不带make和g要先通过系统包管理工具把基础编译环境装上否则configure直接就会卡在找不到编译器的步骤上。最后还想再说几句实操上的心里话老实讲Qt源码包的编译过程不难但特别磨心态因为整个环节又多又长任何一个依赖没装都会报一些看上去很生僻的错误。我一开始总想一步到位把所有的模块全编译进去结果反复浪费了不少时间。等真正按项目需求裁剪掉不需要的模块之后这个过程的复杂度一下子降了下来编译时间也能缩短到可控范围。所以我的建议是先花十分钟想清楚自己到底需要哪些模块不需要的直接skip比盲目硬刚那些重型模块要省时省力得多。另外在整个过程中要养成好习惯每次编译出问题多看一眼错误输出的前几行多半就能快速定位到问题源头。本文还有配套的精品资源点击获取