cmake 是一个跨平台的构建系统生成器,它通过编写简单的配置文件(CMakeLists.txt)来管理软件的编译过程,支持多种操作系统和编译器,掌握 cmake 常用命令是高效管理项目构建的关键,以下将详细介绍这些命令的功能、用法及示例。

cmake 命令通常在 CMakeLists.txt 文件中编写,以指令加参数的形式存在,项目初始化命令 project() 是必须的,用于定义项目名称和可选的语言版本。project(MyProject CXX C) 指定项目名称为 MyProject,支持 C++ 和 C 语言。cmake_minimum_required(VERSION 3.10) 用于指定 cmake 最低版本要求,确保新版本特性可用时不会因版本过低而报错。
对于源文件管理,add_executable() 和 add_library() 是核心命令,前者用于生成可执行文件,如 add_executable(myapp main.cpp utils.cpp) 将 main.cpp 和 utils.cpp 编译为 myapp 可执行文件;后者用于生成库文件,add_library(mylib STATIC source1.cpp source2.cpp) 生成静态库,SHARED 则生成动态库,如果需要编译多个源文件,可以使用 file(GLOB SOURCES "*.cpp") 自动匹配目录下所有 cpp 文件,再通过 add_executable(myapp ${SOURCES}) 统一添加。
依赖管理方面,find_package() 用于查找第三方库,如 find_package(Boost 1.70 REQUIRED) 检查 Boost 库是否满足版本要求,找到库后,可通过 target_link_libraries() 将库链接到目标,target_link_libraries(myapp PRIVATE Boost::boost),对于系统库,如 pthread,可直接使用 target_link_libraries(myapp pthread)。
包含目录和编译选项的配置也很重要。include_directories() 添加头文件搜索路径,如 include_directories(${PROJECT_SOURCE_DIR}/include);而 target_include_directories() 更推荐,因为它能作用于特定目标,如 target_include_directories(myapp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/headers),编译选项通过 add_compile_options() 或 target_compile_options() 设置,target_compile_options(myapp PRIVATE -Wall -O2) 启用所有警告和优化。

变量和条件控制能提升灵活性。set() 用于定义变量,如 set(MY_VAR "value"),${MY_VAR} 引用变量值,条件判断使用 if(),if(UNIX) 执行平台相关命令,循环通过 foreach() 实现,如 foreach(item IN LISTS ITEMS_LIST) 遍历列表。
安装规则通过 install() 命令定义,install(TARGETS myapp DESTINATION bin) 将可执行文件安装到 bin 目录,install(FILES header.h DESTINATION include) 安装头文件,打包时,install(EXPORT MyProject DESTINATION lib/cmake/MyProject) 导出目标供其他项目使用,配合 export() 命令生成配置文件。
测试支持通过 enable_testing() 和 add_test() 实现,add_test(NAME mytest COMMAND myapp) 添加测试用例,结合 ctest 命令运行测试。
以下为常用命令的快速参考表格:

| 命令 | 功能 | 示例 |
|---|---|---|
project() |
定义项目名称和语言 | project(MyProject CXX) |
add_executable() |
生成可执行文件 | add_executable(myapp main.cpp) |
add_library() |
生成库文件 | add_library(mylib STATIC source.cpp) |
find_package() |
查找第三方库 | find_package(Boost REQUIRED) |
target_link_libraries() |
链接库到目标 | target_link_libraries(myapp PRIVATE lib) |
include_directories() |
添加头文件路径 | include_directories(include) |
install() |
定义安装规则 | install(TARGETS myapp DESTINATION bin) |
enable_testing() |
启用测试支持 | enable_testing() |
相关问答FAQs
Q1: 如何在 cmake 中添加编译宏定义?
A: 使用 target_compile_definitions() 命令,target_compile_definitions(myapp PRIVATE DEBUG=1) 定义 DEBUG 宏,或通过 add_compile_definitions(DEBUG) 全局定义。
Q2: 如何处理跨平台差异,如 Windows 和 Linux 的不同库?
A: 使用 if() 条件判断平台,if(WIN32) 下链接 ws2_32 库,if(UNIX) 下链接 pthread,如 target_link_libraries(myapp PRIVATE $<$<PLATFORM_ID:Windows>:ws2_32> $<$<PLATFORM_ID:Linux>:pthread>)。
