第一节: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. 声明关系,而不是写流程
相关推荐
在路上看风景15 小时前
19. 成员初始化列表和初始化对象
c++
zmzb010315 小时前
C++课后习题训练记录Day98
开发语言·c++
wdfk_prog15 小时前
[Linux]学习笔记系列 -- [drivers][input]input
linux·笔记·学习
念风零壹15 小时前
C++ 内存避坑指南:如何用移动语义和智能指针解决“深拷贝”与“内存泄漏”
c++
盟接之桥16 小时前
盟接之桥说制造:引流品 × 利润品,全球电商平台高效产品组合策略(供讨论)
大数据·linux·服务器·网络·人工智能·制造
忆~遂愿16 小时前
ops-cv 算子库深度解析:面向视觉任务的硬件优化与数据布局(NCHW/NHWC)策略
java·大数据·linux·人工智能
湘-枫叶情缘16 小时前
1990:种下那棵不落叶的树-第6集 圆明园的对话
linux·系统架构
孞㐑¥16 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
Fcy64817 小时前
Linux下 进程(一)(冯诺依曼体系、操作系统、进程基本概念与基本操作)
linux·运维·服务器·进程
袁袁袁袁满17 小时前
Linux怎么查看最新下载的文件
linux·运维·服务器