跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++

CMake 核心概念与实战:目标、属性、API 及静态库构建

CMake 核心概念与实战应用。涵盖 CMakeLists.txt 基础命令(minimum_required, project, include, install, add_executable),演示了基于 CMake 组织静态库依赖的程序运行流程。重点解析了现代 CMake 的三大核心:目标(Target)、属性(Property)和 API,阐述了属性传递机制(PRIVATE/PUBLIC/INTERFACE)及配置、生成、构建、安装四大工作流程。旨在帮助读者掌握现代 C++ 工程化构建的最佳实践。

苹果系统发布于 2026/3/29更新于 2026/10/25102 浏览
CMake 核心概念与实战:目标、属性、API 及静态库构建

一、CMakeLists 相关命令解释

cmake_minimum_required 命令
  1. 核心作用:用于指定项目所需的最低 CMake 版本。这是一个强制性要求,必须放在项目顶层 CMakeLists.txt 文件的第一行。
  2. 关键参数解释
    • 基本语法形式:
      cmake_minimum_required(VERSION <min> [...<policy_max>] [FATAL_ERROR]) 
      
    • <min>:最重要的参数,用于指定一个最低版本号(例如 3.18)。如果当前运行的 CMake 版本低于此版本,配置将失败。
    • <policy_max> (可选):用于指定一个最高策略版本,此选项较少使用。
    • FATAL_ERROR (可选):显式指定版本不满足时报错并终止流程。对于 CMake 2.6 及以后的版本,这是默认行为,因此现代项目中通常无需再写。
  3. 版本号设置参考:设置版本号时需考虑不同操作系统和发行版的软件源中预装的 CMake 版本。例如 Ubuntu 22.04 约 v3.22,Ubuntu 24.04 约 v3.28。
  4. 为何必须设置:确保项目能在符合要求的构建环境中正确配置,避免因开发者本地 CMake 版本过旧或过新而引发不可预见的错误,保证项目构建的一致性和可重现性。

CMake 操作截图

project 命令
  1. 核心作用:用于指定项目的名称,是 CMake 项目的核心标识。此命令必须放在顶级 CMakeLists.txt 文件的开头位置(通常在 cmake_minimum_required 之后)。
  2. 自动创建变量:执行 project() 后,CMake 会自动创建一系列变量供后续使用,例如:
    • PROJECT_NAME: 项目名称
    • PROJECT_VERSION: 项目的完整版本号
    • PROJECT_SOURCE_DIR: 项目源代码的根目录路径
    • PROJECT_BINARY_DIR: 项目构建的输出目录路径
  3. 主要用途:作为项目的唯一标识;用于自动生成库文件名、配置文件名等;管理项目的版本信息;定义项目源代码和构建结果的路径。
  4. 常见变量使用:
    • PROJECT_NAME 可用于动态库输出名称、cmake 配置文件名称、命名空间名称。
    • PROJECT_VERSION 可用于打印变量、生成 pkg-config 或.cmake 对应的版本配置文件。

CMake 变量截图

注意默认 project 的 languages 是 C 与 CXX。如果确定哪个语言就只写那个,否则就会都生成耗时间。这里一旦写错就会出现问题(比如把 CXX 程序改成 C),会导致找不到对应的编译工具。

include 命令
  1. 核心作用:用于在当前 CMakeLists.txt 的上下文中加载并执行另一个文件(.cmake 脚本)或模块中的 CMake 代码。
  2. 基本语法:
    include(<file|module> [OPTIONAL] [RESULT_VARIABLE <var>]) 
    
    • <file|module>:要包含的文件或模块名。
    • OPTIONAL:可选关键字。如果找不到文件,不会报错,静默忽略。
    • RESULT_VARIABLE <var>:可选关键字。将查找结果存入指定变量 <var> 中。
  3. 文件搜索路径:如果指定的是相对路径,则从当前正在执行的 CMakeLists.txt 所在目录开始查找;如果指定的是绝对路径,则直接加载该路径下的文件。
  4. 模块搜索路径:当参数不是路径格式时,CMake 会将其视为模块名,按顺序搜索名为 <module>.cmake 的文件。
  5. 执行逻辑:被 include 的文件中的 CMake 代码会在当前上下文中立即执行。
  6. 关键变量行为:include 执行外部文件时,会改变以下 CURRENT 系列变量的值:
    • CMAKE_CURRENT_LIST_FILE:变为被包含文件的完整路径。
    • CMAKE_CURRENT_LIST_DIR:变为被包含文件所在的目录路径。
    • CMAKE_CURRENT_SOURCE_DIR 和 CMAKE_CURRENT_BINARY_DIR:保持不变,仍然是包含者(父 CMakeLists.txt)的源目录和构建目录。
install 命令
  1. 核心作用:像 cp 命令一样,把编译好的程序、库文件、头文件、配置文件复制(部署)到指定的系统目录中。
  2. 常用指令:
    • 安装整个目录:install(DIRECTORY 目录/ DESTINATION 目标路径)
    • 安装单个文件:install(FILES 文件.h DESTINATION include)
    • 安装程序/库:install(TARGETS 目标名 DESTINATION bin/lib)
  3. 步骤总结:
    1. 收集:CMake 读取你的 install 命令,记住要安装哪些文件。
    2. 生成:CMake 把这些指令写成一个自动安装脚本 (cmake_install.cmake)。
    3. 执行:当你运行 make install 时,CMake 就运行这个脚本,把文件复制到指定位置。
add_executable 命令
  1. 核心作用:用于指示 CMake 从源代码生成一个可执行文件。这是创建可执行程序(如 .exe)的核心命令。
  2. 关键参数:
    • target_name:必需。指定生成的可执行文件的名称(不含扩展名)。此名称在项目内部必须唯一。
    • source1.cpp ...:必需。指定构建此可执行文件所需的源文件列表。
  3. 输出位置:默认位置是与 CMakeLists.txt 源目录对应的构建目录中。可以通过设置目标的 RUNTIME_OUTPUT_DIRECTORY 属性来更改其默认的输出目录。

二、基于 CMake 组织实现静态库依赖程序运行

重温动静态库
  • 静态库:直接塞进程序里,编译完就能单独运行。优点是不用管用户电脑有没有库,缺点是程序会变大。
  • 动态库:程序运行时才临时调用,需要用户电脑上有这个库文件。优点是程序小,多个程序能共用同一个库,缺点是分发麻烦。

总之,动态库使用的时候需要链接(可达共享);而静态库直接就是归档文件,填进程序即可,无需链接操作。

下面基于顶层 CMakeLists.txt 以及底层 CMakeLists.txt 实现对应的程序与静态库编成可执行程序进行执行。

对应开始目录结构如下:

├── CMakeLists.txt
├── myapp
│   ├── CMakeLists.txt
│   └── main.cpp
└── my_lib
    ├── CMakeLists.txt
    ├── include
    │   └── math.h
    └── src
        ├── add.cpp
        └── sub.cpp

这里我们把对应的 src 里的 cpp 文件以及包含对应 include 里面的 math.h 组成对应的静态库(头文件声明 + 源文件实现)。

编写对应的 main.cpp 出现了问题无法识别对应头文件,因为它在固定的目录找不到 math.h,因此需要添加头文件搜索路径。

对应的静态库生成的 CMakeLists.txt 文件:

# my_lib/CMakeLists.txt
add_library(my_static STATIC src/add.cpp src/sub.cpp)
target_include_directories(my_static PUBLIC include)

主函数结合静态库最终生成对应的执行程序的 CMakeLists.txt 文件:

# myapp/CMakeLists.txt
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE my_static)

顶层 CMakeLists.txt 文件只需要调用前两个底层即可:

# Top CMakeLists.txt
add_subdirectory(my_lib)
add_subdirectory(myapp)

下面进行运行,构建对应的程序及静态库的生成。

如果想要指定对应目录到指定的 build 目录里面,因此就可以调整生成的可执行程序的属性即可。 那两个底层 CMakeLists.txt 进行添加属性设置。如果不指定是顶层 CMake 对应生成的目标目录,它会相对当前的 CMakeLists 目录为相对目录生成对应那些文件。因为它是被顶层 CMake 调用的,因此会生成在 build 文件,但是又要保证与 my_lib 在同一目录,因此会生成在对应 build 的 my_lib 目录里。

删除 build 目录及缓存文件后重新生成,成功生成在指定目录了,运行成功。

三、CMake 的三大核心:目标、属性、API 介绍

概念介绍

现代 CMake 的核心是'目标(Target)'为中心的管理模式。每个库或可执行程序都是一个独立的目标,拥有自己的属性和行为。

  1. 三大核心概念:

    • 目标 (Target):构建系统的基本单元(如一个库 add_library 或一个程序 add_executable)。
    • 属性 (Properties):每个目标所具有的特征或元数据(如包含路径、编译选项、链接库等)。
    • API:用于操作目标及其属性的命令接口(如 target_include_directories, target_link_libraries)。
  2. 关键机制:属性传递

    关键字对当前目标的构建影响是否传播给下游目标?通俗解释
    PRIVATE生效否私有属性:只给自己用,不告诉别人。
    PUBLIC生效是公共属性:自己要用,也告诉别人要用。
    INTERFACE不生效是接口属性:自己不用,但要求别人用。

    这是现代 CMake 最强大的特性。通过 PUBLIC、PRIVATE、INTERFACE 关键字,一个目标的属性可以自动、精确地传递给依赖它的其他目标。

  3. 与面向对象编程的类比:

    • 目标 (Target) ≈ 类 (Class)
    • 属性 (Properties) ≈ 成员属性
    • API 命令 ≈ 成员函数
  4. 最终等式:目标 + 属性 + API + 属性传递机制 = CMake 现代化构建系统的核心。

目标

CMake 中的'目标'就是你想让构建系统帮你生成的东西,主要分三大类:

  • EXECUTABLE:生成可执行程序。
  • 各种 LIBRARY (STATIC, SHARED, MODULE):生成库文件。
  • 特殊目标 (INTERFACE, IMPORTED, ALIAS):不生成文件,用于管理。
属性
  • 全局属性 (Global):整个项目。
  • 目录属性 (Directory):当前文件夹及子文件夹。
  • 目标属性 (Target):单个程序或库(最常用)。
  • 源文件属性 (Source):单个代码文件。
  • 测试属性 (Test):单个测试用例。
  • 安装属性 (Install):要安装的文件。
API
  • 通用读写 (set_target_properties):用来记录或查看某块乐高(目标)的所有属性。
  • 编译阶段 (target_compile_definitions):告诉管理员某块乐高该怎么拼。
  • 链接与输出 (target_link_libraries):告诉管理员哪些乐高块可以拼在一起。
  • 安装与打包 (install):规定拼好的成品如何打包进盒子。
CMake 三大核心工作流程
  1. 配置期:CMake 读取您的 CMakeLists.txt 脚本,登记所有要构建的目标,并记录下您设置的各种属性。
  2. 生成期:CMake 将上一步登记的目标和属性翻译或具体化成底层构建工具(如 Make 或 Ninja)能直接执行的脚本文件。
  3. 构建期:通过 makefile 调用编译器 (gcc/clang) 和链接器 (ld),根据生成的脚本执行编译和链接。
  4. 安装期:利用配置期设置的属性,生成一个安装脚本,用于将构建好的程序和相关文件复制到系统的安装目录中。

一句话:CMake 就是一个自动化项目经理:它先理解您的构建需求(配置),然后制定详细的施工计划(生成),接着指挥工人干活(构建),最后负责产品的打包和部署(安装)。

四、本篇小结

本篇通过学习 CMake 三大核心(目标、属性、API)和完整构建流程(配置、生成、构建、安装),将掌握现代化 C++ 项目管理的关键技能。这些知识将显著提升开发效率和项目可维护性。

目录

  1. 一、CMakeLists 相关命令解释
  2. cmakeminimumrequired 命令
  3. project 命令
  4. include 命令
  5. install 命令
  6. add_executable 命令
  7. 二、基于 CMake 组织实现静态库依赖程序运行
  8. 重温动静态库
  9. my_lib/CMakeLists.txt
  10. myapp/CMakeLists.txt
  11. Top CMakeLists.txt
  12. 三、CMake 的三大核心:目标、属性、API 介绍
  13. 概念介绍
  14. 目标
  15. 属性
  16. API
  17. CMake 三大核心工作流程
  18. 四、本篇小结

更多推荐文章

查看全部
  • Unity VR 高分辨率全景视频播放性能优化
  • Git 原理与使用
  • ERNIE-4.5-0.3B 轻量模型部署指南与实战测评
  • OpenHarmony与华为云IoT智能家居开发指南
  • 使用 AI 视觉编程模型优化 Unity 编辑器插件:从功能实现到界面美化
  • WebPShop 插件:Photoshop 支持 WebP 格式的解决方案
  • 基于大型语言模型的智能 Agent:发展历程、架构与 Langchain 实现
  • Antigravity 配置指南:打造类 VS Code 的 AI IDE
  • Linux 系统安装、故障排除、权限管理与安全配置指南
  • Stable Diffusion 完整训练与推理流程详解(附伪代码)
  • 2025 广西网安竞赛 AWD Web 部分赛后复盘与漏洞分析
  • 基于飞算 JavaAI 的在线图书借阅平台设计与实现
  • HTML+CSS+JavaScript 前端基础知识体系梳理
  • STM32H743 与 STM32F407 串口通信配置与优化实践
  • Seedance 2.0 双分支扩散变换器架构解析与工程实现
  • AI 辅助 9·1 软件安装:环境检测与问题修复方案
  • SLAM Toolbox 机器人定位与建图实践
  • C++ 面向对象编程核心:深入解析继承机制
  • C++显性契约与隐性规则:类型转换
  • 程序员面试复盘:72 次面试经历与 Android Java 高频面试题

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online