CMake 是一种跨平台的构建系统,它使用文本文件(CMakeLists.txt)来描述构建过程,旨在简化 C/C++ 项目的构建、测试和打包。本文将详细讲解 CMake 的基本概念、使用方法、常用命令及功能,以及如何在 C++ 项目中有效地使用 CMake。

1. CMake 的基本概念

  • CMakeLists.txt: CMake 的配置文件,定义了项目的构建设置、依赖关系和目标。
  • 构建目录: 用于存放构建文件(例如所编译的对象文件和可执行文件)的目录。通常建议与源代码目录分开的构建目录(out-of-source build)。
  • 生成器: 生成不同平台和工具链的构建文件的程序,如 Makefile、Ninja、Visual Studio 工程文件等。
  • 指令和命令: CMake 使用各种命令(如 add_executabletarget_link_librariesfind_package 等)来定义构建逻辑。

2. 安装 CMake

CMake 可以在多个操作系统上安装:

  • Windows: 从 CMake 官方网站 下载 Windows 安装程序。
  • Linux: 使用包管理器安装。例如,在 Ubuntu 上:
sudo apt update  
sudo apt install cmake
  • macOS: 使用 Homebrew 安装:
brew install cmake

3. 创建 CMake 项目

3.1 创建目录结构

创建一个简单的 C++ 项目目录结构如下:

my_project/  
├── CMakeLists.txt  
└── src/  
    ├── main.cpp  
    └── utils.cpp  
    └── utils.h

3.2 编写 CMakeLists.txt

在项目根目录下创建 CMakeLists.txt 文件,下面是一个基本示例:

# 设置最低的版本要求  
cmake_minimum_required(VERSION 3.10)  

# 设置项目名称  
project(MyProject VERSION 1.0)  

# 设置 C++ 标准  
set(CMAKE_CXX_STANDARD 11)  
set(CMAKE_CXX_STANDARD_REQUIRED True)  

# 添加可执行文件  
add_executable(MyExecutable src/main.cpp src/utils.cpp)  

# 指定可执行文件的输出目录(可选)  
set_target_properties(MyExecutable PROPERTIES  
    RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

3.3 编写源代码

在 src/ 目录下,创建 main.cpputils.cpp 和 utils.h 文件。

main.cpp:

#include <iostream>  
#include "utils.h"  

int main() {  
    std::cout << "Hello, CMake!" << std::endl;  
    greet(); // 调用 utils.h 中的函数  
    return 0;  
}

utils.h:

#ifndef UTILS_H  
#define UTILS_H  

void greet();  

#endif // UTILS_H

utils.cpp:

#include <iostream>  
#include "utils.h"  

void greet() {  
    std::cout << "Greetings from the utils!" << std::endl;  
}

4. 使用 CMake 构建项目

4.1 进入构建目录

在项目根目录下创建并进入构建目录:

mkdir build  
cd build

4.2 生成构建系统

通过 CMake 配置项目并生成构建文件:

cmake ..
  • .. 表示上一级目录是源代码所在的目录。CMake 将解析 CMakeLists.txt 并生成构建文件。

4.3 构建项目

使用以下命令构建项目:

cmake --build .

执行后将生成 MyExecutable 可执行文件,通常在 build/bin 目录下。

5. CMake 的高级用法

5.1 添加库

CMake 允许创建静态库和共享库。以下是创建一个静态库的示例:

在 CMakeLists.txt 中添加静态库的代码:

# 创建静态库  
add_library(MyLibrary STATIC src/utils.cpp)  

# 指定可执行文件依赖于库  
target_link_libraries(MyExecutable PRIVATE MyLibrary)

5.2 查找包

CMake 可以查找外部库和包(如 Boost、OpenCV 等):

find_package(Boost 1.70 REQUIRED)  
target_link_libraries(MyExecutable PRIVATE Boost::Boost)

5.3 添加子目录

对于大型项目,可以将子项目分离到各自的目录下,并通过 add_subdirectory 将其添加到主项目中。

add_subdirectory(lib) # 假设 lib/ 目录包含 CMakeLists.txt

5.4 CMake 变量和选项

可以在 CMakeLists.txt 中定义变量和选项以控制构建设置:

option(ENABLE_TESTS "Enable tests" ON)  
if(ENABLE_TESTS)  
    # 添加测试  
endif()

5.5 设定配置文件

配置文件可以用来在构建时定义特定的设置:

configure_file(config.h.in config.h)

然后在源代码中包含此头文件。

6. 测试

CMake 还支持测试,在 CMakeLists.txt 中可以添加测试支持:

enable_testing()  

# 创建测试可执行文件  
add_executable(MyTests test_main.cpp)  

# 添加测试  
add_test(NAME MyTests COMMAND MyTests)

7. 常见问题

  • 找不到 CMake: 检查 CMake 是否正确安装,并且已添加到 PATH。
  • 构建目录未清理: 若更改了 CMakeLists.txt,强烈建议先清理构建目录rm -rf build/*后再重新生成。
  • 版本不匹配: 检查 CMake 版本是否满足项目的最低要求