Qt 项目构建入门CMake 完全指南(三)

适合人群: 已安装 Qt,想理解项目是如何构建的新手

前言

很多初学者打开 Qt Creator 就直接开始写代码,但对"为什么能跑起来"毫无概念。当项目出错、找不到库、或者需要添加新文件时,就会茫然无措。

本文的目标是让你真正理解 Qt 项目的构建过程------CMake 到底做了什么,CMakeLists.txt 文件里每一行是什么意思,以及如何在实际项目中正确使用它。


一、构建系统是什么?为什么需要它?

写代码只是第一步,把代码变成可运行的程序需要经历:

scss 复制代码
源代码 (.cpp / .qml)
    ↓  编译器(如 GCC、MSVC)
目标文件 (.o / .obj)
    ↓  链接器
可执行文件 (.exe / app)

当项目只有一个文件时,手动执行编译命令还勉强可以。但真实项目往往有几十甚至几百个文件,还需要链接各种库------这时就需要构建系统来自动化管理这个过程。

CMake 是目前最主流的 C++ 构建系统,Qt 6 已将其作为官方推荐的构建工具。


二、CMake 的工作原理

CMake 本身不直接编译代码,它的工作流程是:

go 复制代码
CMakeLists.txt(你写的构建描述文件)
    ↓  cmake 命令
Makefile 或 build.ninja(平台原生构建文件)
    ↓  make 或 ninja 命令
最终可执行程序

你只需要维护一份 CMakeLists.txt,CMake 会根据当前平台自动生成对应的构建文件。这正是 Qt 跨平台能力的基础之一。


三、安装 CMake 和 Ninja

Qt 6 需要 CMake 3.16 或更高版本,以及 Ninja 构建工具。

方法一:通过 Qt Maintenance Tool 安装(推荐新手)

  1. 打开 Qt Maintenance Tool
  2. 选择 "Add or remove components"
  3. Developer and Designer Tools 下勾选:
    • CMake x.x.x
    • Ninja x.x.x
  4. 点击 Next 完成安装

方法二:单独安装

安装后在终端验证:

bash 复制代码
cmake --version
# 输出类似:cmake version 3.27.0

ninja --version
# 输出类似:1.11.1

四、认识 CMakeLists.txt

每个 Qt 项目的根目录都有一个 CMakeLists.txt 文件,它是整个构建过程的"说明书"。

下面是 Qt Creator 自动生成的一个典型 Qt Quick 项目的 CMakeLists.txt

cmake 复制代码
cmake_minimum_required(VERSION 3.16)

project(MyApp VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Quick)

qt_standard_project_setup(REQUIRES 6.5)

qt_add_executable(MyApp
    main.cpp
)

qt_add_qml_module(MyApp
    URI MyApp
    VERSION 1.0
    QML_FILES
        Main.qml
)

target_link_libraries(MyApp
    PRIVATE Qt6::Quick
)

逐行解析

第 1 行:指定 CMake 最低版本

cmake 复制代码
cmake_minimum_required(VERSION 3.16)

告诉 CMake:"我的项目需要至少 3.16 版本才能正确处理。"如果用户的 CMake 版本太低,会直接报错提示升级,而不是产生奇怪的构建错误。


第 3 行:定义项目基本信息

cmake 复制代码
project(MyApp VERSION 0.1 LANGUAGES CXX)
  • MyApp:项目名称
  • VERSION 0.1:版本号,可选
  • LANGUAGES CXX:声明这是一个 C++ 项目(CXX 是 C++ 的标准缩写)

第 5-6 行:设置 C++ 标准

cmake 复制代码
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

要求使用 C++17 标准,且这是强制要求(REQUIRED ON)。Qt 6 需要 C++17,这两行是标准写法。


第 8 行:查找 Qt 模块

cmake 复制代码
find_package(Qt6 REQUIRED COMPONENTS Quick)

这是最关键的一行。它告诉 CMake 去找 Qt6,并且需要其中的 Quick 模块(用于 QML 开发)。

如果同时需要多个模块,用空格分隔:

cmake 复制代码
find_package(Qt6 REQUIRED COMPONENTS Quick Widgets Network)

常用模块对照:

模块名 用途
Quick QML 和 Qt Quick
Widgets 传统桌面 UI
Network 网络请求
Sql 数据库操作
Charts 图表组件
Multimedia 音视频

第 10 行:Qt 项目标准化设置

cmake 复制代码
qt_standard_project_setup(REQUIRES 6.5)

Qt 6.3 引入的便捷函数,自动配置一些 Qt 项目推荐的默认设置,REQUIRES 6.5 表示需要 Qt 6.5 或更高版本。


第 12-14 行:创建可执行目标

cmake 复制代码
qt_add_executable(MyApp
    main.cpp
)

定义最终要生成的可执行文件名为 MyApp,源文件是 main.cpp。如果有多个 C++ 文件,在这里逐行添加:

cmake 复制代码
qt_add_executable(MyApp
    main.cpp
    backend.cpp
    datamodel.cpp
)

第 16-22 行:添加 QML 模块

cmake 复制代码
qt_add_qml_module(MyApp
    URI MyApp
    VERSION 1.0
    QML_FILES
        Main.qml
)

将 QML 文件注册到构建系统。URI 是 QML 模块的唯一标识符,QML_FILES 下列出所有 .qml 文件。

新增 QML 文件时,需要在 QML_FILES 下手动添加文件名:

cmake 复制代码
QML_FILES
    Main.qml
    components/Button.qml
    components/Header.qml

第 24-26 行:链接 Qt 库

cmake 复制代码
target_link_libraries(MyApp
    PRIVATE Qt6::Quick
)

将 Qt Quick 库链接到 MyAppPRIVATE 表示这个依赖只在 MyApp 内部使用,不对外暴露。

如果 find_package 里加了多个模块,这里也要对应添加:

cmake 复制代码
target_link_libraries(MyApp
    PRIVATE
        Qt6::Quick
        Qt6::Network
        Qt6::Sql
)

五、添加资源文件

项目中常常需要用到图片、字体等资源文件。Qt 提供了 qt_add_resources 将资源打包进可执行文件:

cmake 复制代码
qt_add_resources(MyApp "assets"
    PREFIX "/"
    FILES
        images/logo.png
        fonts/custom.ttf
)

打包后在 QML 中通过 qrc:/ 前缀访问:

qml 复制代码
Image {
    source: "qrc:/images/logo.png"
}

注意: 使用 qt_add_qml_module 时,QML 文件已经自动被处理为资源,不需要重复添加到 qt_add_resources


六、构建一个控制台应用(动手练习)

不带 UI 的控制台应用是理解 CMake 的最佳起点,结构最简单。

第一步:创建项目目录结构

css 复制代码
MyConsoleApp/
├── CMakeLists.txt
└── main.cpp

第二步:编写 main.cpp

cpp 复制代码
#include <QCoreApplication>
#include <QDebug>

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    qDebug() << "Hello from Qt!";
    qDebug() << "Qt version:" << QT_VERSION_STR;

    return 0;
}

第三步:编写 CMakeLists.txt

cmake 复制代码
cmake_minimum_required(VERSION 3.16)

project(MyConsoleApp VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 REQUIRED COMPONENTS Core)

qt_standard_project_setup()

qt_add_executable(MyConsoleApp
    main.cpp
)

target_link_libraries(MyConsoleApp
    PRIVATE Qt6::Core
)

第四步:在 Qt Creator 中打开并运行

  1. 打开 Qt Creator → File → Open File or Project
  2. 选择 CMakeLists.txt 文件(不是 .cpp
  3. 选择 Kit(如 Desktop Qt 6.x.x MinGW)
  4. 点击 Configure Project
  5. Ctrl+R 运行

控制台输出:

csharp 复制代码
Hello from Qt!
Qt version: 6.7.0

七、常见错误与解决方法

错误:Could not find a package configuration file provided by "Qt6"

kotlin 复制代码
CMake Error: Could not find a package configuration file provided by "Qt6"

原因: CMake 找不到 Qt 的安装路径。

解决: 在 Qt Creator 的 Preferences → Kits → CMake Configuration 中确认 CMAKE_PREFIX_PATH 指向了正确的 Qt 安装目录,例如:

javascript 复制代码
C:/Qt/6.7.0/mingw_64

错误:找不到新添加的 QML 文件

原因: 新建 .qml 文件后忘记在 CMakeLists.txtQML_FILES 里登记。

解决:QML_FILES 下添加文件名,然后重新 CMake configure(Qt Creator 通常会自动提示)。


错误:AUTORCC 相关警告

如果同时使用了 qt_add_resources 和旧式的 .qrc 文件,可能看到关于 AUTORCC 的警告。解决方式是统一使用 qt_add_resources 的现代写法,并在 CMakeLists.txt 中明确设置:

cmake 复制代码
set(CMAKE_AUTORCC OFF)

八、Qt Creator 与 CMake 的协作

在 Qt Creator 中,你几乎不需要手动运行 cmake 命令------Creator 会自动处理。但有几个操作要知道:

操作 时机
自动重新 Configure 每次修改并保存 CMakeLists.txt
手动 Configure Build → Run CMake
清理构建 Build → Clean All
查看 CMake 输出 底部 "General Messages" 面板

九、下一步

理解了 CMake 之后,你已经具备了阅读和修改任何 Qt 项目构建配置的能力。接下来建议:

  1. Introduction to QML --- 开始写真正的 Qt 界面代码
  2. Creating a Simple Qt Quick Application --- 在 Qt Creator 中完整走一遍从新建到运行的流程
  3. Qt Quick vs. Widgets --- 了解两种 UI 技术路线的区别,为后续选择打好基础

总结

概念 要点
CMake 作用 描述如何构建项目,生成平台原生构建文件
cmake_minimum_required 声明所需最低 CMake 版本
find_package 查找并引入 Qt 模块
qt_add_executable 定义最终生成的可执行文件及其源文件
qt_add_qml_module 注册 QML 文件到构建系统
target_link_libraries 将 Qt 库链接到目标程序
Qt Maintenance Tool 添加新模块后记得重新 configure
相关推荐
用户908324602732 小时前
Spring AI + RAG + SSE 实现带搜索来源的智能问答完整方案
前端·后端
GISer_Jing2 小时前
阿里开源纯前端浏览器自动化 PageAgent,[特殊字符] 浏览器自动化变天啦?
前端·人工智能·自动化·aigc·交互
清风徐来QCQ2 小时前
js中的模板字符串
开发语言·前端·javascript
成都渲染101云渲染66662 小时前
Houdini+Blender高效渲染方案(高配算力+全渲染器兼容)
前端·系统架构
SuperEugene3 小时前
Vue3 + Element Plus 表格实战:批量操作、行内编辑、跨页选中逻辑统一|表单与表格规范篇
开发语言·前端·javascript
极梦网络无忧3 小时前
基于 Vite + Vue3 的组件自动注册功能
前端·javascript·vue.js
Predestination王瀞潞3 小时前
5.4.3 通信->WWW万维网内容访问标准(W3C):WWW(World Wide Web) 协议架构(分层)
前端·网络·网络协议·架构·www
爱学习的程序媛3 小时前
【Web前端】优化Core Web Vitals提升用户体验
前端·ui·web·ux·用户体验
zabr3 小时前
花了 100+ 篇笔记,我整理出 了一套 AI Agent 工程完全指南
前端·后端·agent