CMake 构建系统概述

关键要点

  • 研究表明,CMake 是一种强大的跨平台构建系统,广泛用于 C++ 项目。
  • 证据倾向于认为,CMake 通过生成本地构建文件(如 Makefile、Visual Studio 项目)简化软件构建。
  • 它似乎可能支持多种平台,包括 Windows、Linux 和 macOS,适合复杂项目。
  • 存在争议,部分开发者认为其脚本语言学习曲线较陡,但社区支持广泛。

CMake 构建系统概述

什么是 CMake?
CMake 是一种跨平台构建系统生成工具,最初于 2000 年由 Kitware 公司开发,旨在解决传统构建工具(如 Make 和 autoconf)在跨平台上的局限性。它不直接编译代码,而是生成本地平台的构建文件(如 Makefile、Visual Studio 项目文件、Ninja 脚本等),方便在不同操作系统(如 Windows、Linux、macOS)上构建软件。CMake 的核心是 CMakeLists.txt 文件,用于描述项目的结构、源文件和构建设置。

如何工作?
CMake 的工作流程分为两步:

  1. 配置阶段:运行 cmake 命令,解析 CMakeLists.txt,生成适合目标平台的构建文件。
  2. 构建阶段:使用生成的构建文件(如 make 或 Visual Studio)编译和链接代码。
    它支持出源构建,将构建文件存储在独立目录(如 build/),避免污染源代码目录。

使用方法
使用 CMake 需要:

  • 创建 CMakeLists.txt,定义项目信息和目标。例如:

     

    cmake_minimum_required(VERSION 3.0.0)
    project(myApp VERSION 1.0 DESCRIPTION "一个简单的 CMake 示例" LANGUAGES CXX)
    add_executable(myApp src/main.cpp)
    target_compile_features(myApp PRIVATE cxx_std_20)

  • 在构建目录运行 cmake .. 生成文件,然后用 cmake --build . 构建项目。

优势
CMake 因其跨平台能力、依赖管理能力和社区支持而受欢迎。相比其他工具:

  • 比 Make 更强大,自动处理依赖;
  • 比 Autotools 更简单,Windows 支持更好;
  • 比 SCons 更快,比 Premake 错误报告更清晰。


详细调研笔记:CMake 构建系统的来龙去脉

CMake 构建系统是现代软件开发中不可或缺的工具,尤其在 C++ 项目中占据主导地位。以下是其定义、历史、工作原理、关键特性、使用方法和优势的详细分析,旨在为读者提供全面的理解。

1. 定义与背景

CMake 是一种跨平台的构建系统生成工具(meta-build system),由 Kitware 公司于 2000 年开发,最初是为了支持 Insight Segmentation and Registration Toolkit (ITK) 的多平台构建。它的核心目标是解决传统构建工具(如 Make 和 autoconf)在跨平台上的局限性,例如 Make 文件高度依赖平台,Windows 上需要额外的工具(如 nmake),而 autoconf 生成的脚本复杂且难以维护。

CMake 的工作方式是通过解析 CMakeLists.txt 文件,生成本地平台的构建文件(如 Unix 的 Makefile、Windows 的 Visual Studio 项目文件、Ninja 构建脚本等),然后由这些本地工具实际执行构建。它的设计理念是“一次编写,处处构建”,适合从简单项目到复杂大型项目的构建需求。

2. 历史与发展

CMake 的开发始于 1999 年,受到美国国家医学图书馆资助,旨在支持 Visible Human Project 下的 ITK 项目。2000 年,CMake 1.0 正式发布,初期功能包括依赖主机 C++ 编译器、生成 Visual Studio 和 Unix makefiles、支持构建程序、静态库和共享库等。

  • 早期发展(2000-2010)
    • CMake 1.0 发布,支持基本的项目定义和源文件管理。
    • 2006 年,CMake 2.0 发布,引入条件构建(if 语句)、变量管理和宏定义,增强灵活性。
    • 被更多项目采用,如 Visualization Toolkit (VTK) 和 ITK,功能扩展到更多平台。
  • 中期发展(2010-2014)
    • 2010 年,CMake 2.8 发布,引入对外部库的自动检测(如 find_package),简化依赖管理。
    • 2014 年,CMake 3.0 发布,标志着“现代 CMake”的开始,强调使用目标(targets)和属性(properties)取代全局变量。这使得 CMakeLists.txt 的编写更加模块化和可维护。
  • 现代发展(2014-至今)
    • 2016 年,CMake 3.7 引入对 C++ 标准库的自动链接,进一步简化 C++ 项目构建。
    • 2020 年,CMake 3.18 引入对 C++ 模块的支持,增强代码依赖管理。
    • 截至 2025 年 6 月 14 日,CMake 4.0 发布,支持替代项目文件名,方便开发者过渡。

以下表格总结了 CMake 的主要发展里程碑:

年份版本主要变化
20001.0基本项目定义和源文件管理,支持跨平台构建。
20062.0引入条件构建、变量管理和宏定义,增强灵活性。
20102.8支持外部库自动检测(如 find_package)。
20143.0强调目标和属性管理,现代 CMake 开始。
20163.7支持 C++ 标准库自动链接,简化 C++ 项目构建。
20203.18引入 C++ 模块支持,增强代码依赖管理。
20224.0支持替代项目文件名,方便开发者过渡。
3. 工作原理

CMake 的工作流程分为两个阶段:

  • 配置阶段
    • 用户运行 cmake <source_dir> 命令,CMake 解析 CMakeLists.txt,根据指定的生成器(如 Unix Makefiles、Ninja)生成本地平台的构建文件。
    • 支持出源构建,用户可以在源目录外创建构建目录(如 build/),运行 cmake .. 生成文件。
  • 构建阶段
    • 使用生成的构建文件调用本地构建工具。例如,生成 Makefile 后,可以运行 make 或 cmake --build . 编译和链接代码。
    • CMake 确保依赖关系正确,自动处理增量构建(只重新构建发生变化的部分)。
  • 关键文件:CMakeLists.txt
    • CMakeLists.txt 是 CMake 的核心配置文件,包含项目信息、源文件列表、构建目标和依赖管理。
    • 示例:

       

      cmake_minimum_required(VERSION 3.0.0)
      project(myApp VERSION 1.0 DESCRIPTION "一个简单的 CMake 示例" LANGUAGES CXX)
      add_executable(myApp src/main.cpp)
      target_compile_features(myApp PRIVATE cxx_std_20)

    • 支持分层结构,根目录的 CMakeLists.txt 可以包含子目录的 CMakeLists.txt,反映项目目录结构。
4. 关键特性

CMake 的功能强大,涵盖以下方面:

  • 跨平台支持
    • 支持生成多种平台的构建文件,包括 Windows(Visual Studio、NMake)、Linux(Make、Ninja)、macOS(Xcode)、iOS、Android 等。
    • 通过单套 CMakeLists.txt 文件实现跨平台构建。
  • 生成器(Generators)
    • 支持多种生成器,如 Unix Makefiles、Ninja、Visual Studio、Xcode、Eclipse CDT 等。
    • 用户可以通过 -G 选项指定生成器,例如 cmake -G "Unix Makefiles" ..。
  • 构建目标(Targets)
    • 支持定义可执行文件(add_executable)、静态库(add_library STATIC)、共享库(add_library SHARED)等。
    • 现代 CMake 强调使用目标属性(如 target_compile_options、target_link_libraries)而非全局变量。
  • 依赖管理
    • 通过 find_package 查找系统库或外部依赖,通过 FetchContent 下载和构建依赖。
    • 自动处理依赖关系,确保下游组件在源文件变化时重新构建。
  • 条件构建
    • 使用 if、elseif、else 等命令支持根据平台、编译器或用户选项进行条件构建。
    • 示例:
      if(WIN32)target_compile_options(myApp PRIVATE /W4)
      else()target_compile_options(myApp PRIVATE -Wall -Wextra)
      endif()

  • 模块化和可维护性
    • 现代 CMake(从 3.0 开始)建议使用目标和属性,而不是全局变量(如 CMAKE_CXX_FLAGS),提高模块化。
    • 示例:target_compile_features(myApp PRIVATE cxx_std_20) 设置 C++ 标准。
  • 包管理(Packaging)
    • 通过 CPack 工具支持生成安装包(如 .deb、.rpm、.msi),便于分发。
  • IDE 支持
    • 可以生成 IDE 项目文件,如 Visual Studio 解决方案、Xcode 项目文件、Eclipse 项目文件等。
  • 其他特性
    • 支持预编译头(从 3.6 开始)、C++ 模块(从 3.28 开始)、JSON 数据提取(从 3.19 开始)。
5. 使用方法

使用 CMake 构建项目通常涉及以下步骤:

  • 创建 CMakeLists.txt
    • 在项目根目录创建 CMakeLists.txt,定义项目信息、源文件和构建目标。
    • 示例:

       

      cmake_minimum_required(VERSION 3.0.0)
      project(myApp VERSION 1.0 DESCRIPTION "一个简单的 CMake 示例" LANGUAGES CXX)
      add_executable(myApp src/main.cpp)
      target_compile_features(myApp PRIVATE cxx_std_20)

  • 创建构建目录
    • 创建独立构建目录(如 build/),支持出源构建。
  • 运行 CMake
    • 在构建目录运行 cmake .. 生成构建文件。
    • 可通过 -G 指定生成器,例如 cmake -G "Unix Makefiles" ..。
  • 构建项目
    • 使用 cmake --build . 或调用本地工具(如 make)构建项目。
  • 安装(可选)
    • 如果定义了安装规则,可运行 cmake --install . 安装项目。
  • 基本命令
    • cmake_minimum_required(VERSION <version>):指定所需 CMake 版本。
    • project(<name> VERSION <version> DESCRIPTION "<desc>" LANGUAGES <lang>):定义项目。
    • add_executable(<name> <source_files>):创建可执行文件。
    • add_library(<name> STATIC|SHARED <source_files>):创建库。
    • target_compile_features(<target> PRIVATE <feature>):设置编译特征。
    • target_compile_options(<target> PRIVATE <options>):设置编译选项。
    • find_package(<package>):查找外部库。
    • option(<var> "<desc>" [value]):定义可选变量。
6. 优势与与其他构建系统的比较

CMake 的优势使其在现代软件开发中备受青睐:

  • 跨平台能力
    • 支持从桌面到移动设备(iOS、Android)再到高性能计算系统的多平台构建。
  • 高效和灵活
    • 自动处理依赖关系,确保只重新构建必要的部分。
    • 支持复杂的条件构建和模块化配置。
  • 与其他构建系统的比较
    • 与 Make 比较:CMake 自动处理依赖关系,而 Make 需要手动维护,适合更复杂的项目。
    • 与 Autotools 比较:Autotools 在 Windows 上表现不佳,而 CMake 更易于跨平台使用。
    • 与 SCons 比较:SCons 速度较慢,而 CMake 更高效。
    • 与 Premake 比较:Premake 的错误报告较差,而 CMake 提供更清晰的错误信息。
    • 与 Ninja 比较:Ninja 是快速构建工具,但需要 CMake 等高层工具生成输入。
    • 与 Meson 比较:Meson 专注于速度,但 CMake 在平台支持(如 iOS、Android)上更全面。
  • 社区和生态
    • CMake 是 C++ 项目的 de-facto 标准,拥有庞大的用户社区和丰富的资源。
    • 被广泛用于开源项目(如 Android NDK、Boost、KDE)和商业软件(如 Netflix、MySQL)。
7. 总结

CMake 构建系统是现代软件开发中不可或缺的工具,尤其在 C++ 项目中。它通过生成本地平台的构建文件,实现了跨平台的软件构建,同时提供了强大的依赖管理、条件构建和模块化配置能力。CMake 的发展历程从 2000 年至今,经历了从简单项目支持到复杂大型项目的演变,尤其在 2014 年后的“现代 CMake”阶段,强调了目标和属性的使用,提高了构建脚本的可读性和可维护性。

对于开发者来说,掌握 CMake 是高效管理跨平台项目的关键。通过简单的 CMakeLists.txt 文件,开发者可以轻松定义项目结构、构建目标和依赖关系,从而在不同平台上高效地构建软件。


关键引文

  • CMake 官方网站详细介绍
  • CMake Wikipedia 历史与特性
  • 现代 CMake 初学者指南
  • 构建系统概述与比较

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/87007.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何顺利将电话号码转移到新iPhone?

当您升级到新 iPhone 时&#xff0c;您需要做的第一件事就是转移您的电话号码。幸运的是&#xff0c;以目前的技术&#xff0c;很容易解决如何将电话号码转移到新iPhone上。此外&#xff0c;传输过程也得到了简化。您可以轻松地将旧手机更换为新 iPhone&#xff0c;而不会丢失任…

java面试总结-20250609

DDD领域设计模型怎么理解&#xff1f; mysql和mongoDB分别适用于哪些业务场景&#xff1f; 查询的场景&#xff0c;数量级的差异&#xff1f; mongodb为什么用B树&#xff1f;用的什么数据引擎&#xff0c;部署方式使用什么模式&#xff0c;分片分了多少片&#xff0c;路由方…

使用GpuGeek训练图像分类器:从入门到精通

引言 在当今人工智能蓬勃发展的时代&#xff0c;图像分类作为计算机视觉的基础任务之一&#xff0c;已经广泛应用于医疗诊断、自动驾驶、安防监控等诸多领域。然而&#xff0c;对于许多初学者和中小型企业来说&#xff0c;构建一个高效的图像分类系统仍然面临诸多挑战&#xf…

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …

2025年渗透测试面试题总结-字节跳动[实习]安全研发员(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 字节跳动[实习]安全研发员 1. 攻防演练中得意经历 2. 安全领域擅长方向 3. 代码审计语言偏向 4. CSRF修复…

Springboot短视频推荐系统b9wc1(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,视频分类,视频信息 开题报告内容&#xff1a; 基于Spring Boot的短视频推荐系统开题报告 一、研究背景与意义 随着移动互联网的普及和短视频行业的爆发式增长&#xff0c;用户日均观看短视频时长已突破2小时&#xff0c;但海量内…

使用联邦学习进行CIFAR-10分类任务

在深度学习领域,图像分类任务是一个经典的应用,而CIFAR-10数据集则是图像分类研究中的重要基准数据集之一。该数据集包含10类不同的图像,每类有6,000个32x32像素的彩色图像,共计60,000个图像。在传统的集中式学习中,所有数据都被集中到一个服务器上进行训练。然而,随着数…

【Linux网络编程】基于udp套接字实现的网络通信

目录 一、实现目标&#xff1a; 二、实验步骤&#xff1a; 1、服务端代码解析&#xff1a; Init()&#xff1a; Run()&#xff1a; 2、客户端代码&#xff1a; 主函数逻辑&#xff1a; send_message发送数据&#xff1a; recv_message接收数据&#xff1a; 三、实验结…

2025年想冲网安方向,该考华为安全HCIE还是CISSP?

打算2025年往网络安全方向转&#xff0c;现在考证是不是来得及&#xff1f;考啥证&#xff1f; 说实话&#xff0c;网络安全这几年热得发烫&#xff0c;但热归热&#xff0c;入门门槛也不低&#xff0c;想进这个赛道&#xff0c;技术、项目经验、证书&#xff0c;缺一不可。 …

【系统架构设计师-2025上半年真题】综合知识-参考答案及部分详解(回忆版)

更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 【第1题】【第2题】【第3题】【第4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15题】【第16题】【第17题】【第18题】【第19题】【第20~21题】【第…

「Java EE开发指南」如何用MyEclipse创建一个WEB项目?(一)

在本文中&#xff0c;您可以找到有关WEB项目的信息。将了解&#xff1a; Web项目结构和参数Web开发生产力工具JSP代码完成和验证 这些特性在MyEclipse中可用。 MyEclipse v2025.1离线版下载 一、Web项目结构 用最简单的术语来说&#xff0c;MyEclipse Web项目是一个Eclips…

Elasticsearch:使用 ES|QL 进行地理空间距离搜索

作者&#xff1a;来自 Elastic Craig Taverner 在 Elasticsearch 查询语言&#xff08;ES|QL&#xff09;中探索地理空间距离搜索&#xff0c;这是 Elasticsearch 地理空间搜索中最受欢迎和最有用的功能之一&#xff0c;也是 ES|QL 中的重要特性。 想获得 Elastic 认证吗&#…

列举开源的模型和推理框架

当然可以&#xff01;下面是一个系统性的列表&#xff0c;按 开源大模型&#xff08;LLM&#xff09; 和 推理框架 两大类列出&#xff0c;并配上简要说明。 &#x1f9e0; 一、开源大语言模型&#xff08;LLMs&#xff09; 名称发布者语言能力模型大小特点LLaMA 2 / 3Meta英文…

深入讲解一下 Nomic AI 的 GPT4All 这个项目

我们来深入讲解一下 Nomic AI 的 GPT4All 这个项目。 这是一个非常优秀和流行的开源项目&#xff0c;我会从**“它是什么”、“为什么它很重要”、“项目架构和源码结构”以及“如何使用”**这几个方面为你全面剖析。 一、项目概述 (Project Overview) 简单来说&#xff0c;…

力扣HOT100之技巧:287. 寻找重复数

这道题真的是中等题吗&#xff1f;我请问呢&#xff1f;&#xff1f;我怎么觉得是困难题呢&#xff1f; 这道题的思路太难想了&#xff0c;想不出来&#xff0c;直接去看的这位大佬的题解&#xff0c;写得很清楚。 这道题可以将其转化为环形链表问题&#xff0c;可是为什么只要…

QT log4qt 无法生成日志到中文的路径中的解决方案

一.使用log4qt时,应用程序安装在带有中文路径下,导致无法生成日志到安装目录中? 问题描述:如下的配置文件,log4j.appender.File.File 后面跟随的路径是当前路径,你可能觉得自己的日志能够生成在当前路径中,如果你试着用自己的程序双击启动一个文件时,你会发现日志生成在…

让 Deepseek 写电器电费计算器小程序

微信小程序版电费计算器 以下是一个去掉"电器名称"后的微信小程序电费计算器代码&#xff0c;包含所有必要文件&#xff1a; 1. app.json (全局配置) {"pages": ["pages/index/index"],"window": {"backgroundColor": &q…

第二部分-静态路由实验

目录 一、什么是路由&#xff1f; 1.1.定义 1.2.路由作用 1.3.路由类型 1.3.1.直连路由 1.3.2.静态路由 1.3.3.动态路由 1.3.4.路由表 1.5.路由器的匹配原则 1.6.路由配置 1.6.1.静态路由配置 1.6.2.动态路由配置 二、实验 2.1.静态路由 2.1.1.实验拓扑 2.1.2.实验过程 2.2.缺省…

Could not initialize Logback logging from classpath:logback-spring.xml

jdk21、springboot 3.2.12启动报错找不到logback.xml Logging system failed to initialize using configuration from classpath:logback-spring.xml java.lang.IllegalStateException: Could not initialize Logback logging from classpath:logback-spring.xmlat org.sprin…

NORA:一个用于具身任务的小型开源通才视觉-语言-动作模型

25年4月来自新加坡技术和设计大学的论文“NORA: a Small Open-Sourced Generalist Vision Language Action Model for Embodied Tasks”。 现有的视觉-语言-动作 (VLA) 模型在零样本场景中展现出优异的性能&#xff0c;展现出令人印象深刻的任务执行和推理能力。然而&#xff…