第一节:CMake 简介

第一节:CMake 简介


一、什么是"构建(Build)"

1. 构建的本质

构建 = 将"人类可读的源码"转化为"机器可执行产物"的全过程

至少包含三个核心阶段:

  1. 编译(Compile)
    • .c / .cpp → .o / .obj
    • 由编译器(gcc / clang / cl.exe)完成
  2. 链接(Link)
    • 多个 .o + 库 → 可执行文件 / 库
    • 由链接器(ld / link.exe)完成
  3. 可选阶段
    • 代码生成
    • 资源处理
    • 单元测试
    • 安装(install)
    • 打包(package)

2. 构建 ≠ 编译命令

手写命令:

bash 复制代码
g++ main.cpp -o app

只适合:

  • 单文件
  • 无依赖
  • 无跨平台需求

真实工程一定需要构建系统


二、什么是"构建系统(Build System)"

1. 构建系统的职责

构建系统不是编译器,它负责 "管理"和"调度"

  • 解析工程描述文件
  • 计算文件依赖关系
  • 判断哪些文件需要重新编译
  • 并行执行构建任务
  • 生成中间文件和最终产物

2. 常见构建系统

系统 特点
make 规则简单,依赖时间戳
Ninja 极速、小巧
MSBuild Windows / Visual Studio
Xcode Build Apple 平台
CMake 构建系统生成器

⚠️ 关键点:
CMake 本身不是构建系统,而是"构建系统生成器"


三、CMake 到底是什么?

1. CMake 的官方定义(工程语义)

CMake 是一个跨平台的、开源的、现代化的构建系统生成器

核心特征:

  • 不负责编译
  • 生成平台原生构建文件
  • 再由底层构建工具执行

2. CMake 在构建生态中的位置

text 复制代码
CMakeLists.txt
        ↓
      CMake
        ↓
Makefile / Ninja / VS Project
        ↓
  make / ninja / msbuild
        ↓
   gcc / clang / cl

👉 CMake 的工作 到"生成构建系统"为止


3. CMake 能解决什么问题?

问题 传统方式 CMake
跨平台 多套脚本 一套配置
IDE 切换 手工改 自动生成
依赖管理 易错 目标传播
构建一致性 难保证 强约束
工程规模 难维护 可扩展

四、CMake 的核心设计思想(非常重要)

1. 声明式,而非命令式

你不是在"写怎么编译",而是在声明目标之间的关系

cmake 复制代码
add_executable(app main.cpp)
target_link_libraries(app PRIVATE MyLib)

不是告诉它"先干什么后干什么",

而是告诉它:

"app 依赖 MyLib"


2. 目标(Target)是一切的核心

CMake 的现代哲学是:

Everything is a Target

目标可以是:

  • 可执行文件
  • 静态库
  • 动态库
  • 接口库(只传播属性)

3. 使用要求(Usage Requirements)

目标不仅有产物,还有"我怎么被用":

  • 头文件路径
  • 编译宏
  • 编译选项
  • 链接依赖

并且 可以自动传递给下游目标


五、CMake 的基本构建流程(用户视角)

1. 三阶段模型(非常关键)

(1)配置阶段(Configure)
bash 复制代码
cmake -S . -B build

发生的事情:

  • 解析所有 CMakeLists.txt
  • 创建目标
  • 计算依赖
  • 生成缓存(CMakeCache.txt)

(2)生成阶段(Generate)
  • 根据生成器(Make / Ninja / VS)
  • 输出对应的构建文件

(3)构建阶段(Build)
bash 复制代码
cmake --build build

真正调用:

  • make / ninja / msbuild
  • 编译 & 链接

六、源内构建 vs 源外构建

1. 源内构建(不推荐)

bash 复制代码
cmake .

缺点:

  • 污染源码目录
  • 不可维护
  • 不可并行多配置

2. 源外构建(标准做法)

bash 复制代码
cmake -S . -B build
cmake --build build

优势:

  • 源码目录干净
  • 支持多 build(Debug / Release)
  • 工程级标准实践

七、CMake 的安装(Install)概念

1. 安装 ≠ 构建

构建:

  • 产物在 build 目录

安装:

  • 拷贝到"系统/发布目录"

2. 默认安装前缀

text 复制代码
CMAKE_INSTALL_PREFIX = /usr/local

典型结构:

text 复制代码
/usr/local/bin
/usr/local/lib
/usr/local/include

3. GNUInstallDirs 的意义

  • 为不同系统定义标准安装路径
  • 保证工程可移植性
  • 强烈推荐使用

八、一个最小 CMake 工程的语义拆解

cmake 复制代码
cmake_minimum_required(VERSION 3.18)
project(helloWorld)
add_executable(main main.cpp)

含义逐行解释:

  1. cmake_minimum_required
    • 锁定 CMake 行为策略
    • 防止不同版本语义变化
  2. project
    • 定义工程身份
    • 初始化语言、变量、版本
  3. add_executable
    • 注册一个目标
    • 不做编译,只是"声明"

九、衍生但必须知道的概念(第一节就要有)

1. 生成器(Generator)

CMake 根据生成器决定输出什么构建文件:

  • Unix Makefiles
  • Ninja
  • Visual Studio
  • Xcode
bash 复制代码
cmake -G Ninja ..

2. 构建类型(Build Type)

常见:

  • Debug
  • Release
  • RelWithDebInfo
  • MinSizeRel
bash 复制代码
cmake -DCMAKE_BUILD_TYPE=Release ..

3. CMakeCache.txt

  • 配置阶段生成
  • 保存所有缓存变量
  • 删除 build 就是"重置一切"

十、第一节你必须真正掌握的"底层认知"

如果你只记住几句话,那就记住这些:

  1. CMake 不编译代码
  2. CMake 生成构建系统
  3. Target 是核心抽象
  4. 属性是通过 Target 传播的
  5. 源外构建是工程铁律
  6. 声明关系,而不是写流程
相关推荐
睡觉然后上课2 小时前
LUA的学习
linux·学习·lua
晨晖22 小时前
二叉树遍历,先中后序遍历,c++版
开发语言·c++
M__332 小时前
动规入门——斐波那契数列模型
数据结构·c++·学习·算法·leetcode·动态规划
wangchen_02 小时前
C/C++时间操作(ctime、chrono)
开发语言·c++
vortex52 小时前
Linux 处理以 Null 字节分隔内容的文件
linux·运维·服务器
人工智能训练2 小时前
Docker Desktop WSL 集成配置宝典:选项拆解 + 精准设置指南
linux·运维·服务器·人工智能·docker·容器·ai编程
颜子鱼2 小时前
deepin系统崩溃/无法启动修复
linux
setary03012 小时前
FastDDS之共享内存
c++
QT 小鲜肉3 小时前
【Linux命令大全】001.文件管理之find命令(实操篇)
linux·运维·前端·chrome·笔记