CMake 是一种跨平台的构建系统,它使用文本文件(CMakeLists.txt)来描述构建过程,旨在简化 C/C++ 项目的构建、测试和打包。本文将详细讲解 CMake 的基本概念、使用方法、常用命令及功能,以及如何在 C++ 项目中有效地使用 CMake。
1. CMake 的基本概念
- CMakeLists.txt: CMake 的配置文件,定义了项目的构建设置、依赖关系和目标。
- 构建目录: 用于存放构建文件(例如所编译的对象文件和可执行文件)的目录。通常建议与源代码目录分开的构建目录(out-of-source build)。
- 生成器: 生成不同平台和工具链的构建文件的程序,如 Makefile、Ninja、Visual Studio 工程文件等。
- 指令和命令: CMake 使用各种命令(如
add_executable
、target_link_libraries
、find_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.cpp
,utils.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 版本是否满足项目的最低要求