CMake是C++项目中常用的跨平台构建工具,核心作用是(如Makefile、VS项目文件),解决不同平台(Windows、Linux、Mac)编译差异的问题,尤其适合多文件、多目录的C++项目(比如包含构造函数、析构函数的类文件编译)。以下是CMake的基础用法,从核心概念到实操步骤,贴合C++学习场景逐步讲解。
1. CMake核心基础(必学,覆盖80%基础场景)
CMake的核心是CMakeLists.txt文件(文件名固定,不可修改),所有构建规则都写在该文件中,CMake会根据该文件生成对应的编译脚本,再通过编译工具(如make、VS编译器)完成项目编译。
(1)核心命令(基础必记)
cmake_minimum_required(VERSION 3.20):指定CMake的最小版本(必填,放在文件第一行),版本过低会导致部分命令无法使用,建议选择3.10及以上版本。
project(项目名 [LANGUAGES CXX]):定义项目名称,可选指定支持的语言(CXX代表C++,不写则默认支持C/C++)。可通过${PROJECT_NAME}引用项目名,${PROJECT_SOURCE_DIR}引用项目源码根目录。
set(变量名 变量值):设置变量,用于存储路径、源文件列表、编译参数等,引用变量时需用${变量名}。例如:set(CMAKE_CXX_STANDARD 17)指定C++编译标准为17,set(SRC_LIST main.cpp student.cpp)存储所有源文件路径[2]。
add_executable(可执行文件名 源文件列表):生成可执行文件,第一个参数是最终生成的可执行文件名,后面跟所有需要编译的.cpp文件。
include_directories(头文件路径):指定头文件搜索路径,当.h文件和.cpp文件不在同一目录时,必须添加该命令,否则编译器会找不到头文件。
2. 实操步骤(以多文件C++项目为例)
假设我们有一个包含构造函数、析构函数的C++项目,结构如下(贴合之前的Student类示例):
cpp
StudentProject/
├── include/ # 头文件目录
│ └── Student.h # 包含Student类的声明(构造、析构、成员函数声明)
├── src/ # 源文件目录
│ ├── Student.cpp # 包含Student类的实现(构造、析构、成员函数定义)
│ └── main.cpp # 主函数,创建对象、调用成员函数
└── CMakeLists.txt # CMake配置文件(核心)
(1)编写CMakeLists.txt文件
cpp
# 1. 指定CMake最小版本
cmake_minimum_required(VERSION 3.20)
# 2. 定义项目名称,指定支持C++
project(StudentProject LANGUAGES CXX)
# 3. 设置C++编译标准(与代码兼容,如C++11、C++17)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON) # 强制使用指定的C++标准
# 4. 指定头文件搜索路径(include目录)
include_directories(${PROJECT_SOURCE_DIR}/include)
# 5. 设置源文件列表(src目录下的所有.cpp文件)
set(SRC_FILES
${PROJECT_SOURCE_DIR}/src/Student.cpp
${PROJECT_SOURCE_DIR}/src/main.cpp
)
# 6. 生成可执行文件(可执行文件名:StudentApp,依赖的源文件:SRC_FILES)
add_executable(StudentApp ${SRC_FILES})
(2)执行CMake构建(跨平台通用步骤)
CMake的构建遵循"out-of-source"(源码外构建)原则,建议创建单独的build目录,避免编译文件污染源码目录,步骤如下:
-
创建build目录:在项目根目录(StudentProject)下,执行命令
mkdir build(Windows可手动创建)。 -
进入build目录:执行
cd build。 -
生成编译脚本:执行
cmake ..(".."表示CMakeLists.txt在上级目录),此时会在build目录下生成Makefile(Linux/Mac)或VS项目文件(Windows)。 -
编译项目:执行
cmake --build .(通用命令),或Linux/Mac执行make,Windows打开生成的.sln文件编译,最终会在build目录下生成可执行文件(StudentApp.exe/StudentApp)。
3. 常用进阶用法(贴合C++项目需求)
搜索源文件:当src目录下文件较多时,可使用aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC_FILES),自动检索src目录下所有.cpp文件并存储到SRC_FILES变量中,无需手动罗列。
生成静态库/动态库:使用add_library(库名 STATIC/SHARED 源文件),STATIC表示静态库,SHARED表示动态库,适合将类封装为库供其他项目调用。
嵌套CMake:大型项目可拆分目录,在子目录下创建CMakeLists.txt,父目录通过add_subdirectory(子目录名)调用子目录的配置,实现模块化编译。
设置编译参数:通过set(CMAKE_CXX_FLAGS "-Wall -g")添加编译参数,-Wall显示所有警告,-g生成调试信息,方便调试包含构造/析构的代码。
4. 关键注意事项
CMakeLists.txt文件名必须严格一致,大小写敏感(如不能写成cmakelists.txt),否则CMake无法识别。
路径引用建议使用${PROJECT_SOURCE_DIR}等内置变量,避免写绝对路径,保证项目可移植(跨平台、跨目录)。
修改CMakeLists.txt后,需重新执行cmake ..更新编译脚本,再执行编译命令。
Windows环境下,若未安装VS,可安装MinGW,执行cmake .. -G "MinGW Makefiles"生成MinGW可用的Makefile,再用mingw32-make编译。
补充说明:CMake的核心价值是"跨平台"和"简化编译配置",尤其适合多文件C++项目(比如包含多个类、多个源文件的项目),后续学习继承、多态时,多文件编译会频繁用到CMake,掌握上述基础用法即可应对大部分学习场景。