概述: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(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_DIRproject() 命令所在目录
PROJECT_BINARY_DIR项目构建目录
CMAKE_INSTALL_PREFIX安装前缀
CMAKE_BUILD_TYPE构建类型
CMAKE_CXX_COMPILERC++ 编译器
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