开头部分
提起Qt 6和CMake,很多刚接触的朋友第一反应是:网上教程一大堆,但真正能照着一步步跑通的没几个。尤其当你从qmake体系转过来,或者刚下载完Qt 6的安装包,面对一堆组件不知道选哪个时,那个"第一个项目"的体积会被恐惧无限放大。我想说,这事儿远没你想的那么复杂,Qt 6 + CMake的组合一旦跑通,后面的开发效率会明显高于老一套qmake,而且跨平台编译、对接第三方库、持续集成这些工程化需求,CMake几乎是绕不开的底座。
我这篇文章就围绕"用Qt 6创建一个CMake项目"这件事,先带你搞清楚为什么Qt 6时代CMake成了默认选择,再给你一个可以直接复制的极简工程模板,一行行解读CMakeLists.txt里到底写了什么、为什么要这么写。然后我会把命令行构建和Qt Creator构建两条路都走一遍,顺带把新手最容易栽进去的几个坑——比如组件装错、Kit选错、Qt 5代码在Qt 6里编译不过——挨个摊开讲。这篇文章适合完全没接触过Qt的纯新手,也适合qmake老用户想快速切换到CMake体系的过渡期读者。
1. 为什么Qt 6时代,CMake成了默认构建系统
很多人不知道,Qt官方从Qt 5.15开始就逐步把CMake作为推荐构建工具,到Qt 6发布时,CMake已经是官方支持的“一等公民”,连Qt自己的模块构建都全面迁移到CMake了。这背后有几层很现实的原因。
1.1 qmake的局限与CMake的生态优势
qmake是Qt早期开发的构建工具,它和Qt的模块系统紧密结合,写过qt += core gui的人应该都很熟悉。但qmake有个先天短板:它只服务于Qt项目,出了Qt这个圈子,几乎没人用。这就意味着,你想在项目里引入一个第三方C++库(比如OpenCV、Protobuf、gRPC),就得靠qmake的INCLUDEPATH、LIBS手动指路径,甚至要写QMAKE_CXXFLAGS去折腾编译选项,一旦库本身还带依赖,那就更痛苦了。
CMake完全不同,它是整个C++生态最通用的构建系统之一,几乎所有主流库都提供CMake的find_package支持。你可以在同一个CMake工程里同时管理普通C++模块、集成第三方库、处理跨平台编译选项,然后顺手把Qt加进来作为一个模块,层次分明。对工程化要求高的项目来说,CMake的巨大生态优势是qmake无法替代的。
1.2 Qt 6的模块管理方式向CMake靠拢
Qt 6的模块设计也明显向CMake靠拢了。以前你用qmake,是在.pro文件里声明你要用哪些模块;现在你用CMake,是通过find_package(Qt6 REQUIRED COMPONENTS Widgets)这种标准方式引入Qt模块。你还可以指定版本、指定路径,这为复杂的依赖管理提供了更灵活的手段。
更关键的是,Qt 6自带的工具(比如moc元对象编译器、uic界面编译器、rcc资源编译器)在CMake里都有对应的自动化机制——AUTOMOC、AUTOUIC、AUTORCC。这三个开关帮你自动处理那些繁琐的代码生成步骤。我第一次用qmake时,最烦的就是每次改了带Q_OBJECT的头文件都要手动跑一下moc,或者还要写一堆额外规则;CMake里把这些全包揽了,设置好之后只需要正常写代码,构建系统会自动识别和处理。
1.3 社区和官方工具的倾斜
还有一个原因不得不提:整个C++开源社区对CMake的接受度已经非常高,Qt Creator的CMake支持也在几个大版本里迭代得相当成熟。你在Qt Creator里新建项目,官方向导默认推荐的就是CMake。各种第三方库的文档里,示例基本都优先给CMake写法。几十年积累下来的Stack Overflow问答、项目模板、CI配置脚本,大多都是CMake语境下的。我们做项目的人最怕什么?不是代码难写,是出了问题找不到人问、搜不到解决方案。选CMake,等于站到了整个社区的主流路径上,遇到问题几乎都能搜到现成的讨论。
2. 环境准备里那些最容易被忽视的坑
在动手写代码之前,先把环境配好。很多新手卡在第一步,不是因为CMakeLists.txt写错了,而是Qt组件装漏了、编译器没配对、系统路径不对。我先给你一个稳妥的安装思路,再重点强调几个经常出问题的地方。
2.1 Qt 6安装时组件的选择策略
到Qt官网下载安装器(Qt Online Installer),安装过程中有两步大多数人都会忽略。
第一步是选择安装目录,尽量不要把Qt装到带有中文或空格的路