| 日期 | 内容 | |
|---|---|---|
| 1 | 20260201 | 初版 |
引言:从"魔法"到"工具"
还记得第一次看到CMakeLists.txt时的感觉吗?那些神秘的命令,复杂的语法,仿佛是一种魔法。但今天,我要告诉你:CMake不是魔法,它只是一个工具,而且是一个你可以快速掌握的工具。
让我们在15分钟内,从零开始掌握CMake的核心使用。
一、准备工作:最小化环境配置
1.1 确认CMake已安装
# 打开终端/命令行,输入: cmake --version # 你应该看到类似这样的输出: # cmake version 3.22.1 # CMake suite maintained and supported by Kitware (kitware.com/cmake). # 如果提示找不到命令,请先安装: # Ubuntu/Debian: sudo apt install cmake # macOS: brew install cmake # Windows: 从官网下载安装包或使用 Chocolatey: choco install cmake
1.2 创建学习目录
# 创建一个干净的目录开始学习 mkdir cmake-quickstart cd cmake-quickstart
二、第一个CMake项目:Hello CMake!
2.1 编写最简单的C++程序
创建一个main.cpp文件:
// main.cpp - 我们的第一个程序 #include <iostream> int main() { std::cout << "🎉 Hello CMake!" << std::endl; std::cout << "这是我的第一个CMake项目!" << std::endl; return 0; }2.2 编写CMakeLists.txt(只需3行!)
创建CMakeLists.txt文件:
# CMakeLists.txt # 第1行:指定CMake最低版本 cmake_minimum_required(VERSION 3.10) # 第2行:定义项目名称 project(HelloCMake) # 第3行:创建可执行文件 add_executable(hello main.cpp)
逐行解释:
cmake_minimum_required(VERSION 3.10)告诉CMake需要的最低版本
3.10是相对较旧但功能齐全的版本
保证兼容性
project(HelloCMake)定义项目名称
这个名称会在生成的IDE项目中显示
还会自动定义一些变量:
PROJECT_NAME,PROJECT_SOURCE_DIR等
add_executable(hello main.cpp)创建可执行文件
hello:生成的可执行文件名main.cpp:源代码文件
2.3 构建项目(三步法)
# 第1步:创建构建目录并配置(推荐做法) mkdir build cd build cmake .. # 你会看到类似输出: # -- The C compiler identification is GNU 9.4.0 # -- The CXX compiler identification is GNU 9.4.0 # -- Detecting C compiler ABI info # -- Detecting C compiler ABI info - done # -- Check for working C compiler: /usr/bin/cc - skipped # -- Detecting C compile features # -- Detecting C compile features - done # -- Detecting CXX compiler ABI info # -- Detecting CXX compiler ABI info - done # -- Check for working CXX compiler: /usr/bin/c++ - skipped # -- Detecting CXX compile features # -- Detecting CXX compile features - done # -- Configuring done # -- Generating done # -- Build files have been written to: /path/to/build # 第2步:编译项目 cmake --build . # 输出示例: # Scanning dependencies of target hello # [ 50%] Building CXX object CMakeFiles/hello.dir/main.cpp.o # [100%] Linking CXX executable hello # [100%] Built target hello # 第3步:运行程序 ./hello # Linux/macOS # 或 hello.exe # Windows
三、理解CMake的构建流程
3.1 为什么要有build目录?
项目目录/ ├── CMakeLists.txt # 源代码 ├── main.cpp └── build/ # 构建产物(可删除重建) ├── CMakeCache.txt ├── CMakeFiles/ ├── cmake_install.cmake ├── Makefile # 生成的构建文件 └── hello # 生成的可执行文件
分离构建的好处:
保持源码目录干净
支持多个构建配置(Debug/Release,不同平台)
快速清理:删除build目录即可重新开始
3.2 单行命令构建(更简洁的方式)
# 使用 -B 指定构建目录,自动创建 cmake -B build # 使用 --build 编译 cmake --build build # 更简洁的一行命令 cmake -B build && cmake --build build # Windows下可能需要指定配置 cmake -B build && cmake --build build --config Release
四、添加更多源文件
4.1 多文件项目结构
让我们扩展项目,添加一些功能:
// math_utils.h - 头文件 #ifndef MATH_UTILS_H #define MATH_UTILS_H int add(int a, int b); int multiply(int a, int b); #endif // math_utils.cpp - 实现 #include "math_utils.h" int add(int a, int b) { return a + b; } int multiply(int a, int b) { return a * b; }// main.cpp - 更新后的主程序 #include <iostream> #include "math_utils.h" int main() { std::cout << "🎉 Hello CMake!" << std::endl; int sum = add(10, 20); int product = multiply(5, 6); std::cout << "10 + 20 = " << sum << std::endl; std::cout << "5 * 6 = " << product << std::endl; return 0; }4.2 更新CMakeLists.txt
cmake_minimum_required(VERSION 3.10) project(HelloCMake) # 方法1:列出所有源文件 add_executable(hello main.cpp math_utils.cpp ) # 方法2:使用变量(更清晰) set(SOURCE_FILES main.cpp math_utils.cpp ) add_executable(hello ${SOURCE_FILES})4.3 处理头文件目录
如果头文件在子目录中:
项目目录/ ├── include/ │ └── math_utils.h ├── src/ │ ├── main.cpp │ └── math_utils.cpp └── CMakeLists.txt
更新CMakeLists.txt:
cmake_minimum_required(VERSION 3.10) project(HelloCMake) # 添加可执行文件 add_executable(hello src/main.cpp src/math_utils.cpp ) # 指定头文件搜索路径 target_include_directories(hello PRIVATE include) # 解释: # PRIVATE - 只影响当前目标(hello) # PUBLIC - 影响当前目标和依赖它的目标 # INTERFACE - 只影响依赖它的目标,不影响自己五、常用配置选项
5.1 设置C++标准
cmake_minimum_required(VERSION 3.10) project(HelloCMake) # 方法1:全局设置(影响所有目标) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 必须支持 set(CMAKE_CXX_EXTENSIONS OFF) # 禁用编译器扩展 # 方法2:针对特定目标设置(现代CMake推荐) add_executable(hello main.cpp) set_target_properties(hello PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF )5.2 调试与发布模式
# 配置为Debug模式(默认) cmake -B build -DCMAKE_BUILD_TYPE=Debug # 配置为Release模式(优化) cmake -B build -DCMAKE_BUILD_TYPE=Release # 在CMakeLists.txt中判断 if(CMAKE_BUILD_TYPE STREQUAL "Debug") message(STATUS "Debug模式 - 启用调试信息") add_definitions(-DDEBUG_MODE) else() message(STATUS "Release模式 - 启用优化") endif()六、实战:完整的入门模板
6.1 完整的最小项目模板
# CMakeLists.txt - 新手友好模板 cmake_minimum_required(VERSION 3.10) # 项目基本信息 project(MyProject VERSION 1.0.0 DESCRIPTION "我的C++项目" LANGUAGES CXX ) # 设置C++标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # 收集源文件 file(GLOB_RECURSE SOURCES "src/*.cpp") file(GLOB_RECURSE HEADERS "include/*.h") # 创建可执行文件 add_executable(${PROJECT_NAME} ${SOURCES}) # 包含头文件目录 target_include_directories(${PROJECT_NAME} PRIVATE include) # 在Debug模式添加调试信息 if(CMAKE_BUILD_TYPE STREQUAL "Debug") target_compile_definitions(${PROJECT_NAME} PRIVATE DEBUG=1) endif() # 安装目标(可选) install(TARGETS ${PROJECT_NAME} DESTINATION bin)6.2 对应的项目结构
myproject/ ├── CMakeLists.txt # 构建配置 ├── README.md # 项目说明 ├── include/ # 公共头文件 │ └── *.h ├── src/ # 源代码 │ ├── main.cpp │ └── *.cpp └── build/ # 构建目录(不要提交到Git) ├── CMakeCache.txt ├── Makefile └── myproject # 生成的可执行文件
七、常见问题与解决
7.1 CMake找不到我的文件?
# 错误:源文件路径不对 # ❌ 错误写法(假设文件在src目录下) add_executable(app main.cpp) # 找不到main.cpp # ✅ 正确写法 add_executable(app src/main.cpp) # 或者改变工作目录 add_executable(app main.cpp) # 但要在src目录运行CMake
7.2 "No such file or directory" 错误?
# 错误:没有包含头文件目录 # ❌ 错误写法 add_executable(app src/main.cpp) # main.cpp包含"#include "utils.h"" # ✅ 正确写法 add_executable(app src/main.cpp) target_include_directories(app PRIVATE include)
7.3 如何清理构建?
# 方法1:删除build目录 rm -rf build/ # 方法2:使用CMake的clean目标(如果有) cmake --build build --target clean # 方法3:使用out-of-source构建,直接删除目录即可
八、快速参考卡片
8.1 最常用的5个命令
# 1. 项目定义 project(项目名 [版本] [描述]) # 2. 创建可执行文件 add_executable(目标名 源文件1.cpp 源文件2.cpp ...) # 3. 创建库 add_library(库名 STATIC/SHARED 源文件.cpp) # 4. 包含头文件目录 target_include_directories(目标名 PRIVATE/PUBLIC 路径) # 5. 链接库 target_link_libraries(目标名 PRIVATE/PUBLIC 库名)
8.2 三步构建法(记住这个!)
# 第1步:配置(configure) cmake -B build # 第2步:构建(build) cmake --build build # 第3步:运行(run) ./build/你的程序名
8.3 常用变量
${PROJECT_NAME} # 项目名称 ${CMAKE_SOURCE_DIR} # CMakeLists.txt所在目录 ${CMAKE_BINARY_DIR} # build目录 ${CMAKE_CXX_FLAGS} # C++编译器标志 ${CMAKE_BUILD_TYPE} # Debug/Release九、立即动手:15分钟挑战
挑战任务:创建个人计算器程序
创建目录
my-calculator编写
CMakeLists.txt(参考6.1模板)// 实现加、减、乘、除函数创建
src/calculator.cpp实现函数创建
src/main.cpp使用计算器构建并运行
挑战完成检查:
# 你的项目应该能这样构建 cd my-calculator cmake -B build cmake --build build ./build/my-calculator # 或 my-calculator.exe # 输出示例: # 欢迎使用计算器! # 15 + 27 = 42 # 50 - 23 = 27
十、从Makefile迁移到CMake
10.1 Makefile vs CMake对比
# Makefile示例 CC = g++ CFLAGS = -I./include -std=c++17 TARGET = app SRCS = main.cpp utils.cpp $(TARGET): $(SRCS) $(CC) $(CFLAGS) -o $@ $^ clean: rm -f $(TARGET)
cmake
# 等价的CMakeLists.txt cmake_minimum_required(VERSION 3.10) project(app) set(CMAKE_CXX_STANDARD 17) add_executable(app main.cpp utils.cpp) target_include_directories(app PRIVATE include)
优势对比:
✅ 更简洁易读
✅ 自动检测编译器
✅ 跨平台支持
✅ IDE项目生成
总结:你已经掌握了CMake基础!
回顾学习要点:
✅CMakeLists.txt三要素:版本、项目、目标
✅分离构建目录:保持源码干净
✅多文件管理:使用变量或直接列出
✅头文件包含:
target_include_directories✅C++标准设置:确保兼容性
你现在可以:
创建单文件CMake项目
管理多文件项目
构建和运行程序
设置基本的编译选项
从Makefile迁移到CMake