CMake
定义
CMake是一类“构建系统生成器”,而非编译器的替代品。[2]开发者在源码目录中编写名为 CMakeLists.txt 的文本文件,用一套与平台无关的指令说明有哪些源文件、要生成哪些库和可执行文件、依赖哪些外部组件,CMake据此再输出对应环境的原生构建文件。[5]
程序本身以命令行的cmake命令为主入口,另提供cmake-gui与ccmake等界面,用于编辑配置变量并查看生成结果。[6]
原理
CMake的工作分成两个阶段。先是配置阶段:读取CMakeLists.txt,探测系统中可用的编译器、头文件、库和可选功能,把结果写进构建目录中的缓存文件,例如 CMakeCache.txt;随后是生成阶段:由选定的生成器把缓存的配置翻译成makefile、Ninja构建文件或IDE工程。[5]
生成器是这套机制的核心。同一个工程可以指定 Unix Makefiles、Ninja、Visual Studio 或 Xcode 等不同后端,输出的文件再交回各自的本地编译环境执行,因此源码树无需随平台改动。[3]CMake默认推荐“源外构建”,即把产物放在独立于源码的目录,这样一份源码可以同时保留多个构建树,删除构建目录也不会影响源代码。[6]
描述工程的语言是CMake自有的解释型脚本语言,支持变量、列表、字符串处理、条件判断、函数与宏,以及包含其他模块文件。[7]较新的用法以“目标”为中心,通过 target_link_libraries 一类命令给每个库声明公开与私有的编译选项、包含路径和依赖,使依赖方自动继承所需设置。[8]
发展历程
1999年,Kitware受美国国家医学图书馆委托,为开源医学影像工具包ITK开发一套跨平台构建环境;最初的方案正是CMake的起点,主要设计者包括Bill Hoffman。[4]此前的VTK使用过一个叫pcmaker的小程序,把Unix的Makefile转成Windows的NMake文件,Hoffman在此基础上加入自己的设想,并参考了Unix的configure脚本思路。[9]关于最早实现年份,官方时间线把创建标为2000年,另有资料记作1999年开始研制、2000年首次实现;可以确认的是2001年前后已出现1.0分支并持续开发。[4][8]
2002年起,CMake依次替换了VTK与ParaView的构建系统,来自洛斯阿拉莫斯、桑迪亚等国家实验室的合作与经费随之进入。[4]2006年是关键节点:KDE社区在Alexander Neundorf推动下改用CMake,各大Linux发行版随之打包分发CMake,用户规模迅速扩大,官方时间线将其称为转折点。[4]
此后CMake持续扩展能力:2011年加入Ninja生成器,2016年LLVM放弃autoconf转向CMake,2017年Visual Studio开始内置对CMake工程的支持,2020年前后着手支持C++20模块。[4]2025年3月28日,CMake 4.0发布,这是自2014年3.0之后首次大的主版本更替,同时取消了与3.5之前版本的兼容,旧工程若声明过低的最低版本会在配置时报错。[10]
应用
CMake最常见的用途是为C、C++工程提供一套通用于Windows、Linux、macOS的构建描述,同一份配置还能面向Android、iOS以及高性能计算集群。[3]对需要交叉编译的场景,可以通过工具链文件指定目标平台的编译器与查找路径,从而在不改动工程配置的前提下产出目标平台程序。[6]
除构建之外,CMake还带有若干配套组件:CTest负责运行测试并可与CDash汇总结果,CPack可制作Linux、Windows、macOS上的安装包,ExternalProject模块用于在构建期间下载和编译外部工程。[3][4]这些组件让同一套工程定义覆盖构建、测试、打包与安装环节。[8]
采用CMake的项目覆盖多个领域,开源方面包括Boost、Blender、KDE、MySQL、FreeCAD、WebKit等,LLVM、VTK、ParaView、ITK也属于其使用方。[7][4]桌面与移动端的集成开发环境亦提供直接支持,例如Visual Studio、Qt Creator、CLion、KDevelop可读取其工程配置。[7]
局限
掌握CMake需要专门投入时间,这是长期存在的抱怨。CMake社区曾就此讨论:多数脚本语言的技能可以迁移到别的项目,而学CMake只对CMake本身有用,因此使用者容易抵触,加上分号分隔列表、引号与转义等细节容易出错,新手往往在一次失败尝试后改换其他工具。
向后兼容策略也在累积复杂度。为使旧工程在新版本下行为不变,CMake引入了策略机制与版本声明,CMake 4.0又直接移除对3.5以前版本的兼容,这使部分长期未维护的工程在升级后需要修改版本声明或加补丁才能配置成功。[10][11]
作为生成器,CMake不直接调用编译器完成编译,实际编译与链接仍依赖本机工具链,因此排查结果错误时要区分是配置阶段还是后端构建工具的问题。[5]另有观点指出其扩展能力有限,为新语言或新流程增加支持往往需要改动CMake本身并理解生成器内部机制,而不只是编写插件。[12]
参见
参考资料
- 软件包:cmake(4.3.0~rc3-1) [引用日期2026-10-29]
- softwareheritage.org 上的网页 [引用日期2026-10-29]
- CMake: The Standard Build System [引用日期2026-10-29]
- History of CMake [引用日期2026-10-29]
- devel/cmake - The NetBSD Packages Collection [引用日期2026-10-29]
- README.build.md [引用日期2026-10-29]
- CMake — Википедия - CMake (МФА [ˈsiːmeɪk]; от англ [引用日期2026-10-29]
- Bill Hoffman [引用日期2026-10-29]
- epfl.ch 上的网页 [引用日期2026-10-29]
- [ANNOUNCE] CMake 4.0.0 available for download [引用日期2026-10-29]
- stackoverflow.com 上的网页 [引用日期2026-10-29]
- isocpp.org 上的网页 [引用日期2026-10-29]