概述:CMake 使用手册,涵盖基础配置、常用命令和最佳实践。
0x01、CMake 简介
CMake 是一个跨平台的构建系统生成工具,可以生成 Makefile、Ninja、Visual Studio 等多种构建文件。
工作流程
CMakeLists.txt → CMake → 构建文件(Makefile/VS项目) → 编译器 → 可执行文件
0x02、基础配置
最小配置
cmake_minimum_required(VERSION 3.10)
project(MyProject VERSION 1.0.0 LANGUAGES CXX)
add_executable(myapp main.cpp)设置 C++ 标准
# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# 或使用 target 方式(推荐)
target_compile_features(myapp PUBLIC cxx_std_17)设置输出目录
# 可执行文件输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# 库文件输出目录
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)0x03、常用命令
project - 项目定义
project(MyProject
VERSION 1.0.0 # 版本号
DESCRIPTION "描述" # 项目描述
LANGUAGES CXX C # 支持的语言
)
# 访问项目变量
message("项目名: ${PROJECT_NAME}")
message("版本: ${PROJECT_VERSION}")
message("源码目录: ${PROJECT_SOURCE_DIR}")add_executable - 添加可执行目标
# 基本用法
add_executable(myapp main.cpp)
# 多文件
add_executable(myapp
main.cpp
utils.cpp
helper.cpp
)
# 使用变量
set(SOURCES
main.cpp
utils.cpp
)
add_executable(myapp ${SOURCES})add_library - 添加库目标
# 静态库
add_library(mylib STATIC lib.cpp)
# 动态库
add_library(mylib SHARED lib.cpp)
# 接口库(头文件 only)
add_library(mylib INTERFACE)
# 模块库
add_library(mymodule MODULE module.cpp)target_link_libraries - 链接库
# 链接私有依赖
target_link_libraries(myapp PRIVATE mylib)
# 链接公共依赖(会传递给依赖此目标的其他目标)
target_link_libraries(myapp PUBLIC mylib)
# 链接接口依赖(只对使用者可见)
target_link_libraries(mylib INTERFACE external_lib)target_include_directories - 添加头文件目录
# 私有头文件目录
target_include_directories(myapp PRIVATE include)
# 公共头文件目录
target_include_directories(myapp PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
)
# 系统头文件(不产生警告)
target_include_directories(myapp SYSTEM PRIVATE /usr/local/include)target_compile_definitions - 添加编译定义
# 定义宏
target_compile_definitions(myapp PRIVATE
DEBUG_MODE
VERSION=1
NAME="MyApp"
)target_compile_options - 添加编译选项
# GCC/Clang 选项
target_compile_options(myapp PRIVATE
-Wall
-Wextra
-O2
)
# 条件编译选项
if(MSVC)
target_compile_options(myapp PRIVATE /W4)
else()
target_compile_options(myapp PRIVATE -Wall -Wextra)
endif()0x04、条件判断
平台判断
if(WIN32)
# Windows 平台
elseif(UNIX)
# Unix/Linux 平台
elseif(APPLE)
# macOS 平台
endif()
if(MSVC)
# Visual Studio
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
# GCC
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Clang
endif()构建类型
# 设置默认构建类型
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
# 根据构建类型设置选项
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(myapp PRIVATE DEBUG)
target_compile_options(myapp PRIVATE -g -O0)
elseif(CMAKE_BUILD_TYPE STREQUAL "Release")
target_compile_options(myapp PRIVATE -O3)
endif()0x05、查找依赖
find_package
# 查找包
find_package(Boost 1.70 REQUIRED COMPONENTS filesystem system)
# 使用
target_link_libraries(myapp PRIVATE
Boost::filesystem
Boost::system
)
# 查找 OpenCV
find_package(OpenCV REQUIRED)
target_link_libraries(myapp PRIVATE ${OpenCV_LIBS})
# 查找 Qt
find_package(Qt6 COMPONENTS Core Widgets REQUIRED)
target_link_libraries(myapp PRIVATE Qt6::Core Qt6::Widgets)find_library
find_library(MYLIB
NAMES mylib mylib64
PATHS /usr/local/lib /opt/lib
)
if(MYLIB)
target_link_libraries(myapp PRIVATE ${MYLIB})
endif()find_path
find_path(MYLIB_INCLUDE_DIR
NAMES mylib.h
PATHS /usr/local/include
)
if(MYLIB_INCLUDE_DIR)
target_include_directories(myapp PRIVATE ${MYLIB_INCLUDE_DIR})
endif()0x06、自定义命令
add_custom_command
# 生成文件
add_custom_command(
OUTPUT generated.h
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/generate.py
DEPENDS generate.py
COMMENT "Generating header file"
)
# 构建后执行
add_custom_command(TARGET myapp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_SOURCE_DIR}/config.ini
${CMAKE_BINARY_DIR}/bin/config.ini
COMMENT "Copying config file"
)add_custom_target
add_custom_target(copy_assets
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/assets
${CMAKE_BINARY_DIR}/bin/assets
COMMENT "Copying assets"
)
add_dependencies(myapp copy_assets)0x07、子目录管理
add_subdirectory
# 添加子目录
add_subdirectory(src)
add_subdirectory(lib/mylib)
add_subdirectory(tests)目录结构:
project/
├── CMakeLists.txt
├── src/
│ └── CMakeLists.txt
├── lib/
│ └── mylib/
│ └── CMakeLists.txt
└── tests/
└── CMakeLists.txt
0x08、安装规则
# 安装可执行文件
install(TARGETS myapp
RUNTIME DESTINATION bin
)
# 安装库
install(TARGETS mylib
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
# 安装头文件
install(FILES
include/mylib.h
DESTINATION include
)
# 安装目录
install(DIRECTORY include/
DESTINATION include
)0x09、常用变量
| 变量 | 说明 |
|---|---|
CMAKE_SOURCE_DIR | 顶层 CMakeLists.txt 所在目录 |
CMAKE_BINARY_DIR | 构建目录 |
CMAKE_CURRENT_SOURCE_DIR | 当前 CMakeLists.txt 所在目录 |
CMAKE_CURRENT_BINARY_DIR | 当前构建目录 |
PROJECT_SOURCE_DIR | project() 命令所在目录 |
PROJECT_BINARY_DIR | 项目构建目录 |
CMAKE_INSTALL_PREFIX | 安装前缀 |
CMAKE_BUILD_TYPE | 构建类型 |
CMAKE_CXX_COMPILER | C++ 编译器 |
CMAKE_SYSTEM_NAME | 目标系统名 |
0x10、构建命令
命令行构建
# 创建构建目录
mkdir build && cd build
# 配置
cmake ..
# 指定生成器
cmake -G "Visual Studio 17 2022" ..
cmake -G "Ninja" ..
# 指定构建类型
cmake -DCMAKE_BUILD_TYPE=Release ..
# 指定安装目录
cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
# 构建
cmake --build .
# 指定并行数
cmake --build . -- -j4
# 安装
cmake --install .0x11、示例项目
完整示例
cmake_minimum_required(VERSION 3.15)
project(MyApp
VERSION 1.0.0
LANGUAGES CXX
DESCRIPTION "A sample application"
)
# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 设置输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# 查找依赖
find_package(Boost 1.70 REQUIRED COMPONENTS filesystem)
# 源文件
set(SOURCES
src/main.cpp
src/utils.cpp
)
# 创建可执行文件
add_executable(myapp ${SOURCES})
# 头文件目录
target_include_directories(myapp PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
)
# 链接库
target_link_libraries(myapp PRIVATE
Boost::filesystem
)
# 编译定义
target_compile_definitions(myapp PRIVATE
PROJECT_VERSION="${PROJECT_VERSION}"
)
# 安装规则
install(TARGETS myapp RUNTIME DESTINATION bin)更新时间: 2026-03-27