CMake 使用完整指南
一、CMake 简介
CMake 是一个跨平台的自动化构建工具,通过编写 CMakeLists.txt
文件描述项目构建规则,可生成不同平台(如 Linux/Makefile、Windows/Visual Studio)的本地构建文件。核心优势:
- 跨平台:支持 Windows、Linux、macOS
- 简化构建流程:自动处理依赖关系
- 模块化管理:支持大型项目结构
二、安装 CMake
Linux
# Ubuntu/Debian
sudo apt install cmake
# CentOS
sudo yum install cmake
Windows
- 访问 CMake官网 下载安装包
- 安装时勾选 "Add to PATH"
- 验证安装:
cmake --version
三、基础用法
1. 最小化项目
项目结构:
project/
├── main.c
└── CMakeLists.txt
CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(MyProject)
add_executable(myapp main.c)
构建步骤:
mkdir build && cd build
cmake ..
make
2. 多源文件项目
# 手动指定文件
add_executable(app main.cpp utils.cpp)
# 自动收集源文件
file(GLOB SOURCES "src/*.cpp")
add_executable(app ${SOURCES})
3. 包含头文件目录
include_directories(include) # 添加头文件搜索路径
target_include_directories(app PUBLIC include) # 更推荐的方式
四、进阶场景
1. 生成静态库/动态库
生成静态库:
add_library(mylib STATIC src/mylib.cpp)
生成动态库:
add_library(mylib SHARED src/mylib.cpp)
2. 链接库文件
# 链接系统库
target_link_libraries(app PUBLIC pthread)
# 链接自定义库
add_subdirectory(lib) # 包含子目录
target_link_libraries(app PUBLIC mylib)
3. 多目录项目结构
项目结构:
project/
├── CMakeLists.txt
├── src/
│ └── main.cpp
└── lib/
├── CMakeLists.txt
├── include/
│ └── mylib.h
└── src/
└── mylib.cpp
根目录 CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(MyProject)
add_subdirectory(lib)
add_executable(app src/main.cpp)
target_link_libraries(app PUBLIC mylib)
lib/CMakeLists.txt:
add_library(mylib STATIC src/mylib.cpp)
target_include_directories(mylib PUBLIC include)
五、高级功能
1. 条件编译
option(USE_OPENMP "Enable OpenMP support" ON)
if(USE_OPENMP)
find_package(OpenMP REQUIRED)
target_link_libraries(app PUBLIC OpenMP::OpenMP_CXX)
endif()
2. 添加编译选项
target_compile_options(app PRIVATE -Wall -Wextra)
3. 生成配置文件
configure_file(config.h.in config.h)
config.h.in:
#define VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define VERSION_MINOR @PROJECT_VERSION_MINOR@
六、最佳实践
- 外部构建:始终在
build
目录执行构建 - 避免全局设置:优先使用
target_xxx
命令 - 版本管理:
set(MyProject_VERSION_MAJOR 1)
set(MyProject_VERSION_MINOR 0)
- 跨平台处理:
if(WIN32)
# Windows 特定设置
elseif(UNIX)
# Linux 特定设置
endif()
七、常用命令速查
命令 | 功能 |
---|---|
project() | 定义项目名称 |
add_executable() | 创建可执行文件 |
add_library() | 创建库文件 |
target_link_libraries() | 链接库文件 |
find_package() | 查找外部依赖 |
install() | 定义安装规则 |
八、参考资源
通过本指南,您可快速掌握从简单项目到复杂工程构建的CMake使用技巧。建议结合实践项目加深理解!
参考资料:
[1] https://blog.csdn.net/iuu77/article/details/129229361
[2] https://zhuanlan.zhihu.com/p/534439206
[3] https://zhuanlan.zhihu.com/p/500002865
[4] http://www.360doc.cn/article/9008018_296357404.html
[5] https://zhuanlan.zhihu.com/p/640680428
[6] https://m.blog.csdn.net/ZBraveHeart/article/details/132736292
[7] https://developer.aliyun.com/article/309821
[8] https://m.blog.csdn.net/az44yao/article/details/144727273
[9] https://m.blog.csdn.net/KgCrystal/article/details/133569398
[10] https://zhuanlan.zhihu.com/p/720220887
[11] https://blog.csdn.net/gitblog_06679/article/details/143333724
[12] https://blog.csdn.net/qq_41375609/article/details/110535697
[13] https://www.runoob.com/cmake/cmake-tutorial.html
直接回答
- CMake 是一个跨平台的构建系统,用于管理 C++ 项目的编译和构建。
- 它通过
CMakeLists.txt
文件生成适合不同平台的本地构建文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 项目文件。 - 它支持跨平台构建、测试和打包,适合团队协作和多平台开发。
安装与设置
CMake 可从 cmake.org/download 下载,适用于 Windows、macOS 和 Linux。安装后,运行 cmake --version
检查版本。
基本使用
创建一个简单项目:
-
编写
main.cpp
:#include <iostream> int main() { std::cout << "Hello, World!" << std::endl; return 0; }
-
创建
CMakeLists.txt
:cmake_minimum_required(VERSION 3.20) project(MyProject) add_executable(myapp main.cpp)
-
构建:
mkdir build; cd build; cmake ..; make; ./myapp
。
意外细节
CMake 不仅限于 C++,还支持其他语言,如 C 和 Python,增加了其灵活性。
详细报告
CMake 是一个强大的开源工具,广泛用于管理软件的构建、测试和打包过程,尤其在 C++ 项目中。它通过生成适合不同平台的本地构建文件(如 Makefile、Visual Studio 项目文件或 Ninja 文件),确保跨平台兼容性。以下是关于 CMake 使用的全面指南,涵盖从安装到高级主题的各个方面。
引言
什么是 CMake?
CMake 是一个跨平台的构建系统,允许开发者通过 CMakeLists.txt
文件定义软件的构建方式。它生成本地构建文件,适应不同的操作系统和开发环境,如 Unix 的 Makefile、Windows 的 Visual Studio 项目文件或 macOS 的 Xcode 项目文件。
为什么使用 CMake?
- 跨平台兼容性:CMake 支持在 Windows、macOS 和 Linux 上生成本地构建文件,方便在不同平台上构建项目。
- 一致的构建过程:通过单一配置文件,团队可以轻松共享和维护构建设置,减少平台差异带来的问题。
- 易于协作:适合大型团队开发,确保所有成员使用相同的构建流程。
- 扩展性:CMake 支持测试(通过 CTest)和打包(通过 CPack),提供完整的开发生命周期管理。
安装
CMake 的安装过程因平台而异,可从 cmake.org/download 获取最新版本。以下是各平台的安装步骤:
-
Windows:
- 下载适合 x64 或 i386 的 MSI 安装程序(如 cmake-3.31.6-windows-x86_64.msi)。
- 运行安装程序,完成安装。
-
macOS:
- 使用 Homebrew 安装:
brew install cmake
。 - 或下载 DMG 文件(如 cmake-3.31.6-macos-universal.dmg),双击安装。
- 使用 Homebrew 安装:
-
Linux:
- 使用包管理器安装,例如 Ubuntu 上运行
apt-get install cmake
。 - 或下载源代码(如 cmake-3.31.6.tar.gz),解压并按照 README.rst 编译安装。
- 使用包管理器安装,例如 Ubuntu 上运行
安装完成后,运行 cmake --version
检查版本,确保正确安装。
入门指南
为了帮助初学者快速上手,我们将创建一个简单的“Hello, World!” 项目。
-
创建项目目录:
-
在终端中运行:
mkdir myproject cd myproject
-
-
编写源代码:
-
创建
main.cpp
,内容如下:#include <iostream> int main() { std::cout << "Hello, World!" << std::endl; return 0; }
-
-
创建
CMakeLists.txt
:-
在项目目录下创建
CMakeLists.txt
,内容如下:cmake_minimum_required(VERSION 3.20) project(MyProject) add_executable(myapp main.cpp)
-
cmake_minimum_required
指定所需的最低 CMake 版本。 -
project
定义项目名称。 -
add_executable
定义可执行目标myapp
,使用main.cpp
作为源文件。
-
-
构建项目:
-
创建构建目录并导航:
mkdir build cd build
-
运行 CMake 生成构建文件:
cmake ..
-
根据生成器类型(默认 Unix Makefiles),运行构建命令:
make
-
运行可执行文件:
./myapp
-
输出应为 “Hello, World!”。
-
对于 Windows 用户,可以指定 Visual Studio 生成器:
cmake -G "Visual Studio 16 2019" ..
然后使用 Visual Studio 打开生成的解决方案文件。
管理项目
在实际项目中,源文件通常分布在多个目录中,CMake 提供了灵活的方式来组织和管理这些文件。
-
组织源文件:
-
使用
add_subdirectory
包含子目录。例如,项目结构如下:myproject/ ├── src/ │ ├── main.cpp │ └── helper.cpp └── CMakeLists.txt
-
在根目录的
CMakeLists.txt
中添加:add_subdirectory(src)
-
在
src/CMakeLists.txt
中定义目标:add_executable(myapp main.cpp helper.cpp)
-
-
定义目标:
-
可执行文件:使用
add_executable
,如上例。 -
库文件:使用
add_library
定义静态库或动态库。例如:add_library(mylib STATIC mylib.cpp) add_executable(myapp main.cpp) target_link_libraries(myapp mylib)
-
库类型包括
STATIC
(静态库)、SHARED
(动态库)和MODULE
(模块库)。默认类型由BUILD_SHARED_LIBS
变量控制。
-
-
头文件和链接:
-
使用
include_directories
包含头文件目录,或更现代的方式使用target_include_directories
:target_include_directories(mylib PUBLIC include)
-
以下是库和可执行文件的详细对比:
类型 | 命令 | 描述 |
---|---|---|
可执行文件 | add_executable | 生成可运行程序,需指定源文件 |
静态库 | add_library(... STATIC) | 编译为 .a 或 .lib 文件,链接时嵌入 |
动态库 | add_library(... SHARED) | 编译为 .so 或 .dll 文件,运行时链接 |
模块库 | add_library(... MODULE) | 用于动态加载的插件,通常不直接链接 |
处理依赖
现代项目通常依赖外部库,CMake 提供了多种方式来管理这些依赖。
-
查找系统库:
-
使用
find_package
查找已安装的系统库。例如,查找 Boost 库:find_package(Boost REQUIRED) include_directories(${Boost_INCLUDE_DIRS}) target_link_libraries(myapp ${Boost_LIBRARIES})
-
find_package
支持模块模式(查找Find<PackageName>.cmake
)和配置模式(查找<PackageName>Config.cmake
)。默认先尝试模块模式,若失败则使用配置模式。
-
-
使用外部库:
-
对于未安装的库,可以使用
FetchContent
下载并包含。例如,下载 Google Test:include(FetchContent) FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest GIT_TAG release-1.10.0 ) FetchContent_MakeAvailable(googletest)
-
FetchContent
在配置时下载内容,支持 Git、URL 等多种来源。
-
以下是依赖管理的常见方法对比:
方法 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
find_package | 已安装的系统库或 CMake 支持的库 | 简单,系统级支持,版本管理 | 依赖系统安装,可能不适合自定义库 |
FetchContent | 未安装的库,需下载 | 自动下载,适合开源库,版本可控 | 增加构建时间,可能需要网络连接 |
构建配置
CMake 允许配置不同的构建类型(如 Debug、Release),并设置编译器标志。
-
设置构建类型:
-
使用
CMAKE_BUILD_TYPE
变量,例如:set(CMAKE_BUILD_TYPE Debug)
-
常见类型包括 Debug(调试模式,带调试信息)和 Release(发布模式,优化性能)。
-
-
设置编译器标志:
-
使用
target_compile_options
设置目标特定的编译选项。例如:if(CMAKE_BUILD_TYPE MATCHES "Release") target_compile_options(myapp PRIVATE -O2 -Wall) else() target_compile_options(myapp PRIVATE -O0 -g) endif()
-
也可以使用生成器表达式:
target_compile_options(myapp PRIVATE "$<IF:$<CONFIG:Release>,-O2,-O0>")
-
测试与 CTest
测试是开发周期的重要部分,CMake 集成了 CTest 工具来运行和报告测试结果。
-
启用测试:
-
在
CMakeLists.txt
中添加:enable_testing()
-
-
添加测试:
-
使用
add_test
定义测试。例如:add_executable(test_myapp test_main.cpp) add_test(NAME mytest COMMAND test_myapp)
-
-
运行测试:
-
进入构建目录,运行:
ctest
-
可选参数包括
-V
(详细输出)和-R
(运行匹配正则表达式的测试)。
-
CTest 支持任何返回退出码的命令,零表示成功,非零表示失败,适合 C++ 可执行文件、Python 脚本等。
打包与 CPack
CPack 是 CMake 提供的打包工具,支持生成多种格式的安装包,如 RPM、DEB、NSIS 等。
-
设置 CPack:
-
在
CMakeLists.txt
中添加:set(CPACK_GENERATOR "DEB") set(CPACK_DEBIAN_package_name "myapp") set(CPACK_DEBIAN_package_version "1.0") include(CPack)
-
-
生成包:
-
运行:
cpack
-
生成的包文件(如
myapp_1.0.deb
)位于构建目录下。
-
CPack 支持多种生成器,具体可用生成器可通过 cpack --help
查看。
以下是常见打包格式的对比:
格式 | 平台 | 描述 |
---|---|---|
DEB | Linux (Debian/Ubuntu) | Debian 包,适合 Linux 发行版 |
RPM | Linux (Red Hat) | Red Hat 包,适合 RHEL/CentOS 系统 |
NSIS | Windows | Windows 安装程序,图形界面安装 |
DMG | macOS | macOS 磁盘镜像,适合 macOS 应用分发 |
高级主题
对于复杂项目,CMake 提供了许多高级功能。
-
自定义命令和目标:
-
使用
add_custom_command
定义构建过程中的自定义命令。例如:add_custom_command(TARGET myapp PRE_BUILD COMMAND script.sh COMMENT "Running script" VERBATIM)
-
configure_file
用于生成文件:configure_file(input.txt output.txt @ONLY)
-
-
生成器表达式:
-
用于条件设置属性。例如:
target_link_options(myapp PRIVATE "$<IF:$<CONFIG:Debug>,-Wl,--verbose,-v,-Wl,--verbose,-v,>")
-
支持根据配置(Debug/Release)、平台等动态调整构建规则。
-
-
交叉编译:
-
通过工具链文件定义目标平台。例如:
set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_C_COMPILER arm-linux-gcc) set(CMAKE_CXX_COMPILER arm-linux-g++)
-
运行 CMake 时指定工具链文件:
cmake -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake ..
-
-
平台特定配置:
-
使用条件语句根据平台设置不同选项。例如:
if(CMAKE_SYSTEM_NAME STREQUAL "Windows") # Windows 特定设置 else() # 其他平台 endif()
-
最佳实践
为了保持 CMake 代码的整洁和可维护性,建议遵循以下最佳实践:
- 保持整洁:将
CMakeLists.txt
分割为多个文件,使用add_subdirectory
组织大型项目。 - 避免重复:使用函数和宏(如
function
和macro
)封装重复逻辑。 - 文档化:在 CMake 文件中添加注释,说明复杂逻辑。
- 跨平台测试:在不同平台上测试构建系统,确保兼容性。
- 版本控制:将
CMakeLists.txt
纳入版本控制系统(如 Git),跟踪更改。
资源
以下是进一步学习的资源:
- CMake 官方文档
- CMake 教程
- CMake 社区 Wiki
- 书籍和在线课程可参考 CMake 官方资源页面
关键引用
- CMake Documentation and Community
- CMake Reference Documentation — CMake 4.0.0-rc4 Documentation
- Getting Started with CMake
- CMake Tutorial — CMake 4.0.0-rc4 Documentation
- Step 1: A Basic Starting Point — CMake 4.0.0-rc4 Documentation
- Quick CMake tutorial | CLion Documentation
- CMake - Upgrade Your Software Build System
- About CMake
- Resources
- cmake(1) — CMake 4.0.0-rc4 Documentation
- CPack — CMake 4.0.0-rc4 Documentation
- ctest(1) — CMake 4.0.0-rc4 Documentation
- FetchContent — CMake 4.0.0-rc4 Documentation