目录
[1. 核心文件](#1. 核心文件)
[2. 核心流程](#2. 核心流程)
[1. 版本与项目声明](#1. 版本与项目声明)
[2. 变量操作](#2. 变量操作)
[3. 构建目标命令](#3. 构建目标命令)
[4. 目录与头文件](#4. 目录与头文件)
[5. 调试信息](#5. 调试信息)
一、什么是CMake
Cmake 是一个开源的跨平台自动化构建工具,用于管理软件的构建。它通过独立于平台的配置文件(CMakeLists.txt )生成适用于不同平台的构建文件,如:Makefile 、Ninja 文件、Visual Studio工程文件,从而简化了软件项目的编译与构建流程。它是C/C++项目的主流构建方案。
二、CMake核心优势
CMake支持跨平台,兼容多种操作系统和编译器。通过CMakeLists.txt文件,用户可以根据自身需求灵活定义项目结构、依赖项和编译选项,避免了手动编写复杂的构建脚本。
CMake还支持自动化构建,能够检测系统上的库和工具,可以减少大量配置工作。
一次编写,多平台构建,避免了不同平台的重复开发。
三、CMake核心概念
1. 核心文件
CMakeLists.txt:CMake的核心配置文件,定义项目、源文件、编译选项、依赖等(文件名必须为这个,注意大小写)
CMakeCache.txt:CMake生成的缓存文件,存储编译配置,一般不需要手动修改
build目录:比较推荐的构建目录(源码外构建),所有生成的产物都存放这里,避免污染源码
2. 核心流程
CMake构建步骤:先配置 再构建
bash
# 步骤1:进入构建目录,执行 cmake 生成构建文件(Makefile/VS工程)
cd build && cmake MyProject # MyProject 表示源码目录(包含CMakeLists.txt)
# 步骤2:执行构建(编译代码)
make # Linux/macOS(生成Makefile时)
# 或打开VS工程编译(Windows生成.sln时)
四、CMake基本语法
1. 版本与项目声明
bash
# 1. 指定CMake最低版本(不写会报错)
cmake_minimum_required(VERSION 3.10)
# 2. 声明项目名(可选指定语言:C/CXX/None,默认C+CXX)
project(MyProject
VERSION 1.0.0 # 项目版本(可选)
LANGUAGES C CXX # 支持的语言(可选,None表示无编译)
)
2. 变量操作
CMake变量分为 普通变量、环境变量、缓存变量
bash
# 1. 定义/赋值普通变量(set)
set(SOURCE_FILES src/main.cpp src/utils.cpp) # 列表型变量(空格分隔)
set(INCLUDE_DIR include) # 字符串变量
set(CMAKE_CXX_STANDARD 11) # 内置变量(指定C++标准)
# 2. 读取变量(${变量名})
include_directories(${INCLUDE_DIR})
# 3. 追加变量(APPEND)
set(SOURCE_FILES ${SOURCE_FILES} src/foo.cpp)
# 或简化:list(APPEND SOURCE_FILES src/foo.cpp)
# 4. 环境变量($ENV{变量名})
message("PATH: $ENV{PATH}") # 打印系统PATH
set(ENV{CC} gcc) # 设置环境变量(临时)
# 5. 缓存变量(-D参数传入,持久化)
set(MY_OPTION ON CACHE BOOL "自定义开关") # 可通过 cmake -DMY_OPTION=OFF .. 修改
3. 构建目标命令
CMake核心是目标(Target),可分为可执行文件、静态库和动态库
| 命令 | 作用 |
|---|---|
add_executable(目标名 源码) |
生成可执行文件 |
add_library(目标名 类型 源码) |
生成库(类型:STATIC 静态库 / SHARED 动态库 / MODULE 模块库,默认 STATIC) |
target_link_libraries(目标名 依赖) |
给目标链接依赖(库 / 其他目标) |
示例:
bash
# 生成可执行文件(目标名:my_app,源码:SOURCE_FILES变量)
add_executable(my_app ${SOURCE_FILES})
# 生成静态库(目标名:utils_lib,源码:src/utils.cpp)
add_library(utils_lib STATIC src/utils.cpp)
# 给my_app链接utils_lib库(顺序:目标在前,依赖在后)
target_link_libraries(my_app utils_lib)
# 链接系统库(如pthread)
target_link_libraries(my_app pthread)
4. 目录与头文件
bash
# 1. 包含头文件目录(全局,不推荐)
include_directories(include /usr/local/include)
# 2. 给指定目标设置头文件目录(推荐,作用域更精准)
target_include_directories(my_app
PRIVATE # 仅当前目标可见
include
PUBLIC # 依赖该目标的其他目标也可见
${PROJECT_SOURCE_DIR}/public/include
)
# 3. 添加子目录(子目录需有CMakeLists.txt)
add_subdirectory(src) # 加载src目录的CMakeLists.txt
5. 调试信息
bash
# message(级别 内容),常用级别:STATUS(普通)、WARNING(警告)、FATAL_ERROR(致命错误)
message(STATUS "项目名:${PROJECT_NAME}")
message(WARNING "这是警告信息")
# message(FATAL_ERROR "编译终止") # 触发后CMake配置终止
五、简单项目构建演示
假设项目结构如下:
bash
MyProject/
├── CMakeLists.txt # 根目录CMake配置(核心)
├── src/
│ ├── main.cpp # 主程序
│ └── math/
│ ├── CMakeLists.txt # math模块的CMake配置
│ ├── math.cpp # 数学工具
│ └── math.h # 头文件
└── build/ # 构建目录(空,手动创建)
构建根目录CMakeLists.txt:
bash
# 1. 指定CMake最低版本(建议3.10+,兼容大部分平台)
cmake_minimum_required(VERSION 3.10)
# 2. 声明项目信息(名称、版本、支持的语言)
project(MyProject
VERSION 1.0.0
LANGUAGES CXX # 仅需C++,无需C
)
# 3. 设置C++标准(强制生效,跨平台统一)
set(CMAKE_CXX_STANDARD 11) # 可选14/17/20,根据需求调整
set(CMAKE_CXX_STANDARD_REQUIRED ON) # 强制使用指定的C++标准,不降级
set(CMAKE_CXX_EXTENSIONS OFF) # 禁用编译器扩展(如GNU扩展),保证跨平台
# 4. 引入math子模块(src/math目录)
# 子目录必须有自己的CMakeLists.txt,否则报错
add_subdirectory(src/math)
# 5. 构建主程序可执行文件
# 主程序源码:src/main.cpp
add_executable(my_app src/main.cpp)
# 6. 链接math模块(关键:将math库链接到主程序)
# math_lib是src/math/CMakeLists.txt中定义的库目标
target_link_libraries(my_app PRIVATE math_lib)
)
构建src/math/CMakeLists.txt:
bash
# 1. 构建math库(静态库,推荐;如需动态库,将STATIC改为SHARED)
# 源码:math.cpp
add_library(math_lib STATIC
math.cpp
)
# 2. 暴露头文件路径(给主程序使用)
# PRIVATE:仅math_lib内部使用;PUBLIC:主程序也能找到math.h
# ${CMAKE_CURRENT_SOURCE_DIR} 是当前math目录的绝对路径
target_include_directories(math_lib
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
)
六、CMake安装
CMake下载路径:https://cmake.org/download/
详细安装步骤可参考:CMake 安装与配置 | 菜鸟教程
验证安装:打开Terminal,输入cmake --version,确认是否安装成功。