资讯中心

Ubuntu下Qt Creator编译失败排查:工具链、依赖库到环境配置的完整指南

📅 2026/10/29 11:31:24
Ubuntu下Qt Creator编译失败排查:工具链、依赖库到环境配置的完整指南
做 Qt 开发这些年我在 Linux 上遇到的编译失败次数比 Windows 多了一个数量级。不是说 Ubuntu 不行恰恰相反——Ubuntu 的包管理、编译工具链、依赖库和发行版版本耦合得很紧环境一旦不匹配报错会非常“诚实”地暴露出来。每次有朋友抱着笔记本说“我这 Qt Creator 编译死活过不去”我的第一反应通常不是看代码而是先问三句话你的 Ubuntu 是什么版本Qt 是什么方式装的GCC 是哪个版本这三个问题答完问题基本已经解决一半了。这篇文章就是把我在 Ubuntu 上排查 Qt Creator 编译失败的经验整理成一套可复现的方法。内容包括错误类型的快速区分、工具链匹配、依赖库补齐、环境变量和系统资源几个维度最后用一个完整的实战案例串起来。无论你是刚转到 Linux 没几天的新手还是已经踩了不少坑的老手只要能照着这套思路一步步定位绝大多数编译失败都能在一顿饭的工夫内解决而不是像无头苍蝇一样靠反复 Clean 和重装碰运气。1. 先分清编译失败的三个“事发地点”配置阶段、编译阶段、链接阶段排错最忌讳一上来就乱试。我的习惯是先把报错归到三个阶段之一配置阶段、编译阶段、链接阶段。这三个阶段的错误特征完全不同对应的排查手段也完全不同。1.1 配置阶段的报错长什么样配置阶段发生在你点下“构建”按钮之后、真正调用编译器之前。qmake 或 CMake 会先检查你的项目文件、Qt 模块、构建套件是否合法这个阶段报错代码本身往往一行都没编译。典型报错有Project ERROR: Unknown module(s) in QT: websockets——你在.pro文件里声明了 Qt 模块但当前 Qt 环境里没有这个模块。Qt version is not properly installed, please run make install——某个 Qt 组件损坏或路径不对。No suitable kits found——Qt Creator 找不到能用的构建套件通常是因为没配置编译器或 Kit 里选的 qmake 版本与编译器不匹配。Could not find cmake——构建套件里的 CMake 路径不存在。这类错误的特征非常明显输出面板里没有.cpp文件路径也没有行号基本都是“Project ERROR”或“CMake Error at”开头。看到这种格式你就应该知道问题不在代码而在环境配置。处理办法也直接——先检查 Kit 设置和.pro文件。1.2 编译阶段报错与链接阶段报错如何区分编译阶段是真正调用g或clang对每个源文件做语法和类型检查的阶段。这里的报错特征是包含具体的源文件路径和行号例如/home/user/myapp/main.cpp:12:10: fatal error: QNetworkAccessManager: No such file or directory这类错误的本质通常是两种情况要么头文件路径没包含进来要么对应的开发包没装后面第 3 章会细讲。如果报错内容是undefined reference to QWidget::xxx注意这不是编译阶段的错误而是链接阶段的错误——编译器已经成功把你的源码翻译成了目标文件但在把目标文件和库文件拼装成可执行文件时找不到对应函数的实现。链接错误的特征是不带源文件行号而是带着一堆函数名和.o文件路径/usr/bin/ld: main.o: in function MainWindow::MainWindow(...): main.o:(.text0x1a): undefined reference to QNetworkAccessManager::QNetworkAccessManager(QObject*)为什么我要强调区分编译和链接错误因为很多新手看到undefined reference就以为是代码写错反复改语法结果完全没效果。实际上链接错误大概率是漏了库——要么.pro里没加模块要么系统缺某个.so文件。1.3 为什么我建议打开终端手动跑一次构建Qt Creator 的“编译输出”面板确实能显示报错但它会对信息做折叠和过滤有时候关键错误被藏在“Details”里还会混入构建系统的干扰信息比如 “make: *** [Makefile:1234: main.o] Error 1” 这种套娃输出。我的经验是遇到反复看不懂的报错直接打开终端进入项目的构建目录手动执行一次构建。如果用的是 qmake流程是cd /path/to/project mkdir build cd build qmake ../MyProject.pro make -j$(nproc)用 CMake 则是cd /path/to/project mkdir build cd build cmake .. -DCMAKE_PREFIX_PATH/opt/Qt/5.15.2/gcc_64 make -j$(nproc)手动构建有几个好处第一能看到完整报错顺序很多副作用是前一个错误引发的解决根因后后面一片全好第二可以单独执行make -j1避免并行编译下多个错误混在一起难以定位第三能直接感知编译是否在某个文件瞬间崩掉这往往是工具链或内存问题的信号。做完这一步再去改代码或装依赖。2. 工具链配对问题Ubuntu 22.04/24.04 的 GCC 版本和 Qt 版本必须一起考虑很多人容易掉进一个误区编译器只要是最新版就好Qt 也是越新越好。但在 Ubuntu 上这条公理不成立。Ubuntu 每个 LTS 版本都固定了一个默认 GCC 版本而这个 GCC 版本能不能和你的 Qt 版本好好配合是一个必须优先确认的事情。2.1 Ubuntu 不同版本默认带的 GCC 版本先看一张常用对应表Ubuntu 版本默认 GCC 版本常见 Qt 版本兼容性结论20.04 LTSGCC 9.4Qt 5.12 / 5.15比较稳22.04 LTSGCC 11.4Qt 5.15 / Qt 6.xQt 5.15 整体可用老 Qt 5.12 有概率出问题24.04 LTSGCC 13.xQt 6.x / Qt 5.15.2Qt 6 很稳老的 Qt 5.12 基本别想了注意这里说的 GCC 是gcc和g的默认版本。Qt Creator 的构建套件在没有手动调整时会去/usr/bin找gcc、g而这个路径下的版本通常被系统软链到了默认版本。如果你是在 Ubuntu 22.04 上编译一个老项目用的 Qt 还是针对老 ABI 编译的那么 GCC 11 在某些模板实例化场景下可能产生内部错误Internal Compiler Error简称 ICE。这类错误的恐怖之处在于它报错的地方往往不是真正的问题源头——编译器自己先崩了自然没法给出准确诊断。2.2 “internal compiler error” 可能是版本冲突也可能是内存不足先说个真相很多 ICE 跟 GCC 版本无关而是系统内存不足导致cc1plus进程被 OOM killer 杀掉。所以看到类似这样的输出g: internal compiler error: Killed (program cc1plus)先别急着怀疑版本第一件事是free -h看内存。尤其是虚拟机里跑 Ubuntu 的初始内存经常只有 2GB一旦并行编译多个文件内存瞬间爆掉。这种情况加内存或者make -j1就能解决。但如果去掉“Killed”字样是正儿八经的段错误崩溃g: internal compiler error: Segmentation fault (program cc1plus)这时候就要考虑版本匹配问题了。我在 Ubuntu 22.04 GCC 11 老 Qt 5.12.2 的组合下真实遇到过项目里大量使用std::signal和一些复杂模板编译器在优化阶段直接段错误切换到 GCC 9 后一切正常。2.3 在 Kit 里指定旧版 GCC 而不影响系统解决 GCC 版本问题的关键点是不要去动系统默认的 gcc 软链接。有些教程会让你改/usr/bin/gcc的软链这会导致系统里其他软件新编译出问题属于给自己挖坑的骚操作。正确做法是在 Qt Creator 的 Kit 里单独指定旧版编译器。先安装旧版本sudo apt update sudo apt install gcc-9 g-9验证路径ls -l /usr/bin/gcc-9 /usr/bin/g-9然后在 Qt Creator 中操作打开Tools → Options → Kits → Compilers标签页点击 Add → GCCC 编译器路径填/usr/bin/gcc-9C 编译器路径填/usr/bin/g-9回到Kits标签页选择当前使用的 Kit在 Compiler 下拉框中把 C 和 C 都改成刚添加的 GCC 9顺手确认一下该 Kit 的 qmake 路径和 Qt 版本避免多个 Qt 共存时选错。这样切换完之后其他项目仍然可以用默认 GCC 编译而这个特定的 Kit 使用 GCC 9两不冲突。Qt Creator 会为每个构建套件维护独立的构建目录所以两个编译器并行共存没什么负担。3. 依赖模块与库文件缺失大量“找不到符号”报错的真正底牌编译失败里最磨人的一类是依赖问题。Ubuntu 不像 Windows 那样把一堆开发库默认塞给你它默认安装的是最小运行环境很多开发时需要的头文件和.so链接文件必须手动用 apt 安装。这也是“Windows 上编译得好好的到 Ubuntu 上就报错”的高发原因。3.1 从 -lGL 说起链接器找不到库的本质很多 Qt Widgets 工程在 Ubuntu 下编译到最后会在链接阶段报一个很莫名其妙的错/usr/bin/ld: cannot find -lGL-lGL的意思是告诉链接器“去标准库路径里找名为 libGL.so 的文件”。找不到有两种可能一是这个库根本没装二是装了但路径不在链接器的搜索范围内。在 Ubuntu 上最常见的就是 OpenGL 开发包没装。Qt 的 Widgets 模块在 Linux 上默认需要 OpenGL 库来做渲染哪怕你的项目没直接写任何 GL 代码也躲不掉。处理办法sudo apt install libgl1-mesa-dev libglu1-mesa-devlibgl1-mesa-dev会提供libGL.so这个开发链接文件装完之后链接错误自动消失。类似的还有cannot find -lfontconfig、cannot find -ldbus-1等都是同一个套路先确认包名再 apt 安装。为了防止这种问题反复折磨我在新装 Ubuntu 后做 Qt 开发时会一次性装齐常用基础依赖sudo apt install build-essential libgl1-mesa-dev libglu1-mesa-dev \ libxkbcommon-dev libxkbcommon-x11-dev libfontconfig1-dev libdbus-1-devlibxkbcommon-x11-dev和libxcb-*相关包在 Qt 6.5 以上版本里尤其重要因为 Qt 对 Wayland/X11 的支持依赖这些库漏装会在运行时出现 “could not connect to display” 或者 xcb 插件加载失败表现和编译失败一样让人抓狂。3.2 用 pkg-config 和 apt 快速补齐 Qt 模块如果你的.pro文件里写了QT websockets但当前环境没有 WebSockets 模块qmake 会在配置阶段直接报Unknown module(s) in QT。这个错非常直白解决办法就是装对应 dev 包。Ubuntu 下 Qt5 模块和 apt 包名的对应关系大概是Qt 模块apt 包名QtBasecore/gui/widgets/networkqtbase5-devQtDeclarativeQMLqtdeclarative5-devQtWebSocketslibqt5websockets5-devQtChartslibqt5charts5-devQtPrintSupport包含在 qtbase5-dev 中QtToolsuic、rccqttools5-dev装完之后不用重启 Qt Creator只要重新运行 qmake 或 CMake configure 就行。想知道当前 Qt 到底带了哪些模块用 pkg-config 查一下很直观pkg-config --list-all | grep Qt5如果某个模块的包明明装了pkg-config 还是查不到那就得检查 pkg-config 的搜索路径通常是PKG_CONFIG_PATH环境变量指向不对。系统 Qt 的.pc文件一般位于/usr/lib/x86_64-linux-gnu/pkgconfig如果是 Qt 官方安装器装在/opt/Qt/5.15.2/gcc_64那对应的.pc在/opt/Qt/5.15.2/gcc_64/lib/pkgconfig需要手动把这个目录加进PKG_CONFIG_PATH。3.3 .pro 文件里模块声明不对编译能过但链接失败还有一种很隐蔽的情况.pro文件里忘了声明模块但代码里用了对应 API。因为.cpp文件里 include 到的头文件可能在别的模块路径下被顺带找到了所以编译阶段没报错直到链接阶段才恶狠狠丢出一堆undefined reference。比如你用了QNetworkAccessManager但.pro里只有QT core gui没有network。编译可能通过链接必然失败而且报错是一长串 QNetwork 相关的符号找不到非常吓人。解决方式很简单确认用到的模块都写进去QT core gui network如果你项目用了资源文件、翻译文件还要注意CONFIG resources和lrelease相关配置不过这些都是后话。核心思路是看到undefined reference第一反应是回想“我是不是漏了某个 QT 模块”而不是怀疑代码语法。4. 环境变量、缓存和磁盘空间三个容易被忽略的系统级干扰源有些编译失败既不是代码问题也不是工具链问题而是系统级因素在捣乱。这类问题最迷惑因为报错信息经常看起来像是环境坏了。我单独拿一章讲就是因为这些坑踩一次疼一周。4.1 从终端启动和从桌面启动环境变量是两套Ubuntu 桌面环境下从终端敲qtcreator启动和直接在应用菜单点图标启动进程继承的环境变量是完全不同的。终端启动会继承你~/.bashrc里 export 的所有变量比如LD_LIBRARY_PATH、CMAKE_PREFIX_PATH。而应用菜单启动属于图形会话读的是/etc/environment和 systemd user environment不读.bashrc。这就导致一系列“薛定谔的编译失败”你在终端里跑 qmake 和 make 一切正常一回到 Qt Creator 点构建就找不到头文件、找不到库。大概率就是这个原因。排查方法是在 Qt Creator 的菜单栏 Help → System Information 里看环境变量或者直接在项目环境里添加一条临时打印。更简单的做法干脆不要从菜单启动用终端启动 Qt Creator保持编译环境和命令行一致先排除变量问题再说。4.2 LD_LIBRARY_PATH 设置错误带来的“编译成功但运行就崩”编译阶段不依赖LD_LIBRARY_PATH但运行时依赖。如果你看到程序编译通过、链接通过一点运行却报error while loading shared libraries: libQt5Core.so.5: cannot open shared object file: No such file or directory这就是典型的动态库搜索路径问题。Qt 库如果装在/usr/lib/x86_64-linux-gnu比如 apt 安装的 Qt5那系统默认就能找到。但如果你用 Qt 官方在线安装器装到了/opt/Qt/5.15.2/gcc_64/lib这个目录不在标准搜索路径里运行时就找不到。解决方案有两种。一是临时设置环境变量再启动程序export LD_LIBRARY_PATH/opt/Qt/5.15.2/gcc_64/lib:$LD_LIBRARY_PATH ./your_app二是更稳妥的方式在 Qt Creator 的项目设置里Run → Environment添加LD_LIBRARY_PATH指向 Qt 库目录这样团队成员拉下来项目也能直接跑不用每人都去手动配环境。4.3 磁盘满了、/tmp 满、inode 耗尽这些诡异报错别忽略磁盘空间不足会以非常诡异的方式表现为编译失败。编译器在编译时要写大量临时文件如果/tmp分区满了你会在编译阶段看到fatal error: error writing to /tmp/ccXXXXXX: No space left on device别急先用两个命令查df -h df -idf -h看空间使用率df -i看 inode 使用率。inode 耗尽比空间满更隐蔽——磁盘明明还有几十 GB但小文件的数量达到上限照样报 “No space left on device”。如果 inode 满了排查有没有某个目录堆积了大量小文件常见的是 build 目录和~/.cache。4.4 清理 Qt Creator 的 build 缓存Qt Creator 默认启用 shadow build每个 Kit 一个构建目录项目稍微大一点build 目录动辄几个 GB。缓存出问题时也会出现“我明明改了.pro文件重新构建却还在用旧配置”的诡异现象。这时候最高效的操作是- 菜单栏 Build → Clean All - 菜单栏 Build → Run qmake - 再次重新构建如果 Clean 之后问题依旧直接手动删除项目同目录下的 build 文件夹再重新打开项目。别怕删Qt Creator 的 shadow build 就是用来随时重新生成的。删完重来很多“玄学报错”就不治而愈。另外项目构建目录里有个.qmake.stash文件它会缓存 qmake 的配置结果。如果改了.pro文件但 qmake 没感知到删除这个 stash 再 Run qmake 基本都能解决。5. 一次把项目从 Windows 迁到 Ubuntu 的完整编译排错实战前面讲了方法论这一章我以一个真实案例把它串起来。项目的背景很简单一个跨平台的桌面工具在 Windows 上用 Qt 5.15 开发代码没毛病拷贝到 Ubuntu 22.04 上用 Qt Creator 打开.pro文件准备编译结果一路踩坑。5.1 现场报错 Project ERROR: Unknown module(s) in QT: websockets项目在 Windows 上一切都好到了 Ubuntu 上第一次构建qmake 阶段直接拒绝工作Project ERROR: Unknown module(s) in QT: websockets这说明当前 Kit 所使用的 qmake 对应的 Qt 环境里没有 WebSockets 模块。很多人会怀疑是不是 Ubuntu Qt 本身缺东西其实首先要搞清楚一件事当前 Kit 用的到底是哪个 Qt。在 Qt Creator 的Tools → Options → Kits里可以看到 Kit 的 Qt version 路径。同时也可以在终端查qmake -query QT_INSTALL_PREFIX结果如果是/usr说明用的是系统包管理器里的 Qt5如果是/opt/Qt/5.15.2/gcc_64说明用的是 Qt 官方安装器装的 Qt。我这边的情况是系统 Qt5 没问题但只带了基础模块WebSockets 需要单独装开发包sudo apt install libqt5websockets5-dev装完重新构建配置阶段的报错消失。5.2 排查链路改了 .pro 文件却还在报同一个错这里出现一个很容易误导人的插曲我在.pro文件里补充了QT websockets也装了 dev 包再次点击构建居然还是报 Unknown module。当时的第一反应是“是不是 Qt Creator 没重新运行 qmake”。这就是后面提到的缓存问题。因为 shadow build 模式下.pro文件的改动并不会每次都触发 qmake 重新执行Qt Creator 可能还在用旧的 Makefile 里的配置。处理方法很简单Build → Clean All Build → Run qmake Build → Rebuild All如果还是不行就去构建目录里手动删掉.qmake.stash和Makefile再Run qmake一次。改完这个项目才真正进入编译阶段。5.3 第二轮报错链接找不到 GL 库qmake 跑通后代码编译得很顺利但在链接阶段又报/usr/bin/ld: cannot find -lGL这个错误出现得非常稳定。原因我在第 3 章说过Qt Widgets 在 Linux 上必须能找到 OpenGL 的链接库而新装的 Ubuntu 默认没有开发版 GL 库。解决办法一步到位sudo apt install libgl1-mesa-dev这里有人会问我的项目没用 OpenGL 啊Qt Widgets 的绘制引擎在 Linux 上默认走 OpenGL 路线哪怕你只是弹一个最朴素的 QMainWindow 也要链接 GL。所以这个依赖在 Ubuntu 下是无法绕开的装了就行。5.4 第三轮报错运行时找不到动态库链接通过后程序终于生成。但在 Qt Creator 里点 Run程序窗口没弹出来直接给了个对话框找不到libQt5WebSockets.so.5。这是典型的运行时库搜索问题。编译和链接靠的是-lQt5WebSockets程序跑起来后要动态加载对应.so文件如果这个文件不在动态链接器默认路径里就会启动失败。排查手段是使用ldd查看可执行文件的动态库依赖ldd ./your_app | grep not found如果输出里有libQt5WebSockets.so.5 not found说明运行目录或LD_LIBRARY_PATH没覆盖到 Qt 库目录。修复方式是在项目的Run → Environment里加上LD_LIBRARY_PATH/usr/lib/x86_64-linux-gnu具体路径以qmake -query QT_INSTALL_LIBS的输出为准。我见过很多人在.bashrc里加LD_LIBRARY_PATH结果从桌面图标启动程序时依然崩原因就是第 4 章说的环境变量继承问题。在项目自身的 Run Environment 里配置才能真正作用到每次启动过程。5.5 最终验证和这个过程中最重要的几个习惯修复完这三轮报错之后项目在 Ubuntu 22.04 上从配置、编译、链接到运行全链路通畅。整个过程大约花了二十分钟大部分时间不是花在执行命令上而是花在判断“这个报错属于哪个阶段”上。事后复盘这个案例有几个经验是可以复用的第一拿到报错先分类配置阶段的问题别用重装 Qt 来解决第二.pro改了没生效优先想到 Run qmake 和清理临时文件第三Windows 工程迁移到 Ubuntu先主动把libgl1-mesa-dev装上能省一次报错。6. 我在实际踩坑后沉淀下的一点建议踩过几次坑之后我给自己定了一条规矩但凡要在 Ubuntu 上开发 Qt 项目拿到手第一件事不是打开 Qt Creator而是先检查三个环境事实——g --version确认编译器qmake -v确认 Qt 来源pkg-config --modversion Qt5Widgets确认开发包是否完整。这三条输出扫一眼项目往下走会顺很多。还有一个习惯我觉得值得推荐保持在终端里手动执行构建的能力。Qt Creator 是很方便但它把很多细节包装掉了某些信息只有回到命令行才能看见。我在上面实战里遇到的.qmake.stash缓存问题如果不手动清理在 GUI 里点十次 Rebuild 都不会有任何效果。如果你正在被同样的问题折磨不妨先把工具链对齐的事放一放静下心按这里的思路做一次系统检查。很多时候编译失败不是因为你代码写得差而是因为你少给了环境一个恰到好处的配置。

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案