news 2026/4/18 5:01:13

【CMake】

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【CMake】

一、常用 CMake 内置全局变量总表(工程实践版)

1️⃣ 项目与目录相关(最常用)

变量名含义典型使用场景
PROJECT_NAME项目名打印日志、命名 target
PROJECT_SOURCE_DIR顶层源码目录引用源码路径
PROJECT_BINARY_DIR顶层构建目录生成文件路径
CMAKE_SOURCE_DIR最顶层 CMakeLists 所在目录多子项目判断
CMAKE_BINARY_DIR最顶层 build 目录全局输出路径
CMAKE_CURRENT_SOURCE_DIR当前 CMakeLists 目录子目录相对路径
CMAKE_CURRENT_BINARY_DIR当前子目录 build 目录生成中间文件

📌使用频率:极高
📌所有 CMake 项目必用

2️⃣ 编译器与语言相关

变量名含义使用场景
CMAKE_C_COMPILERC 编译器路径判断 gcc / clang
CMAKE_CXX_COMPILERC++ 编译器路径同上
CMAKE_C_COMPILER_ID编译器类型GNU / Clang / MSVC
CMAKE_CXX_COMPILER_IDC++ 编译器类型条件分支
CMAKE_CXX_COMPILER_VERSION编译器版本特性判断
CMAKE_CXX_STANDARDC++ 标准推荐方式
CMAKE_CXX_FLAGS全局 C++ 编译参数老项目常见

示例:

if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") add_compile_options(-Wall) endif()

3️⃣ 构建类型相关(Debug / Release)

变量名含义使用场景
CMAKE_BUILD_TYPE构建类型单配置生成器
CMAKE_CXX_FLAGS_DEBUGDebug 编译参数调试
CMAKE_CXX_FLAGS_RELEASERelease 编译参数性能
CMAKE_CONFIGURATION_TYPES多配置类型VS / Xcode

⚠️ 注意:

  • Makefile / Ninja:用CMAKE_BUILD_TYPE

  • Visual Studio:忽略CMAKE_BUILD_TYPE

4️⃣ 平台 / 系统 / 架构相关(跨平台必用)

变量名含义使用场景
CMAKE_SYSTEM_NAME操作系统Linux / Windows
CMAKE_SYSTEM_PROCESSOR架构x86_64 / aarch64
UNIX是否类 Unix条件判断
WIN32是否 Windows条件判断
APPLE是否 Apple 平台macOS/iOS
CMAKE_SIZEOF_VOID_P指针大小32/64 位判断

示例:

if (CMAKE_SIZEOF_VOID_P EQUAL 8) message(STATUS "64-bit build") endif()

5️⃣ 输出、安装、路径相关(部署必用)

变量名含义使用场景
CMAKE_INSTALL_PREFIX安装前缀make install
CMAKE_RUNTIME_OUTPUT_DIRECTORYexe 输出路径bin 统一
CMAKE_LIBRARY_OUTPUT_DIRECTORYso 输出路径lib 统一
CMAKE_ARCHIVE_OUTPUT_DIRECTORYa 输出路径lib 统一
CMAKE_PREFIX_PATH查找依赖前缀find_package
CMAKE_MODULE_PATH自定义 Find*.cmake第三方库

6️⃣ Generator / 构建系统相关

变量名含义使用场景
CMAKE_GENERATOR生成器类型Ninja / Make
CMAKE_MAKE_PROGRAMmake 程序路径自动化
CMAKE_TOOLCHAIN_FILE工具链文件交叉编译

7️⃣ CMake 自身行为控制(高级)

变量名含义使用场景
CMAKE_VERBOSE_MAKEFILE显示详细命令调试
CMAKE_EXPORT_COMPILE_COMMANDS生成 compile_commands.jsonclangd
CMAKE_POLICY_DEFAULT_CMPxxxx策略控制老项目兼容

二、CMake常见命令

一、项目与基本配置类(Project / Configure)

命令作用典型使用场景
cmake_minimum_required()指定最低 CMake 版本每个项目必须
project()定义项目名、版本、语言项目入口
set()设置变量设置选项、路径
option()定义 ON/OFF 开关是否开启测试、功能
message()打印信息调试 CMake
include()引入模块引入 GNUInstallDirs
if() / elseif() / else()条件判断平台/编译器分支
foreach()循环批量处理目标
cmake_policy()设置策略新旧行为兼容

二、目标(Target)定义类(核心)

命令作用使用说明
add_library()定义库静态 / 动态 / 接口库
add_executable()定义可执行文件主程序
add_custom_target()自定义目标生成文件、脚本
add_custom_command()自定义命令代码生成
add_dependencies()目标依赖控制构建顺序
add_library(ALIAS)别名 target导出库必备

三、Target 属性设置(现代 CMake 核心)

命令作用推荐级别
target_link_libraries()链接库⭐⭐⭐⭐⭐
target_include_directories()头文件路径⭐⭐⭐⭐⭐
target_compile_definitions()宏定义⭐⭐⭐⭐⭐
target_compile_options()编译参数⭐⭐⭐⭐
target_compile_features()语言特性⭐⭐⭐⭐⭐
set_target_properties()设置属性⭐⭐⭐
get_target_property()查询属性⭐⭐

四、源码与文件处理

命令作用使用说明
target_sources()添加源文件动态拆分源码
file()文件操作读/写/拷贝
configure_file()配置头文件生成 config.h
aux_source_directory()收集源码❌ 不推荐
source_group()IDE 分组VS/CLion

五、第三方库与依赖管理

命令作用场景
find_package()查找已安装库系统/包管理器
FetchContent_Declare()声明依赖拉取源码
FetchContent_MakeAvailable()引入依赖现代方式
find_library()查找库文件不推荐
find_path()查找头文件不推荐
pkg_check_modules()pkg-configLinux 库

六、构建控制与生成器

命令作用说明
add_subdirectory()添加子目录模块化项目
enable_language()启用语言Fortran / CUDA
set_property()设置属性高级用法
get_property()获取属性调试

七、安装(install / export / package)

命令作用场景
install()安装目标make install
export()导出 targetsbuild-tree 使用
install(EXPORT)安装 targetspackage
configure_package_config_file()生成 Config.cmakefind_package
write_basic_package_version_file()生成版本文件版本管理
include(GNUInstallDirs)标准目录/usr/lib

八、测试(CTest)

命令作用使用说明
enable_testing()启用测试顶层
add_test()注册测试单元测试
ctest运行测试CI

九、编译器 / 平台判断(常用变量 + 命令)

命令 / 变量作用
CMAKE_CXX_COMPILER_ID编译器类型
CMAKE_SYSTEM_NAME系统名
CMAKE_BUILD_TYPE构建类型
CMAKE_SIZEOF_VOID_P32/64 位
WIN32 / UNIX / APPLE平台宏

十、调试 & 排错(非常实用)

命令作用
message(STATUS ...)打印状态
cmake -LA查看 cache
cmake --trace跟踪执行
cmake --trace-expand展开变量
make VERBOSE=1查看真实命令

十一、反模式(应避免)

命令问题
CMAKE_CXX_FLAGS全局污染
include_directories()不可控
link_libraries()隐式依赖
aux_source_directory()不稳定

十二、“必会命令清单”

如果只记10 个

project add_library add_executable target_link_libraries target_include_directories target_compile_features add_subdirectory find_package install configure_package_config_file

三、CMakeLists与CMakeCache

(1)、CMakeLists.txt

👉 定义:CMakeLists.txt是 CMake 的“源代码文件”,是由项目维护者编写。描述内容包括:项目结构、如何编译,使用的编译器/标准,依赖哪些库,生成哪些目标(exe / so / a)。

👉 本质:构建规则说明书

👉 特点:必须存在(否则无法使用 CMake);可以有多个(每个子目录一个);会被反复解析;不保存状态(每次配置都从头执行)

👉 举例:

project(MyApp LANGUAGES C CXX) add_executable(myapp main.cpp) target_compile_features(myapp PRIVATE cxx_std_17) target_link_libraries(myapp PRIVATE pthread)

(2)、CMakeCache.txt

👉 定义:CMakeCache.txt是 CMake 的“配置结果缓存文件”。是由CMake 自动生成,位于build 目录。其内容是记录:已选择的编译器、构建类型、路径、用户/脚本设置的 cache 变量

👉 本质:一次配置的“结果快照”

👉 特点:不是手写出来的;只在第一次 cmake 配置或 cache 改变时更新;决定“这次 build 实际用什么配置”

👉 举例:

CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++ CMAKE_BUILD_TYPE:STRING=Release CMAKE_INSTALL_PREFIX:PATH=/usr/local

(3)、两者的关系

CMakeLists.txt 负责“怎么算”,
CMakeCache.txt 负责“算完后的结果记住”。

  • CMakeLists.txt = 程序代码

  • CMakeCache.txt = 程序运行后的变量存储

CMakeLists.txt ↓(解析) cmake 配置 ↓(计算变量) CMakeCache.txt(写入) ↓ 生成 Makefile / Ninja / VS 工程

(4)、CACHE 变量机制

1️⃣ 普通变量(不进 cache)
set(FOO 123)
  • 只在当前配置过程中存在

  • 下次 cmake 就没了

2️⃣ Cache 变量(写入 CMakeCache.txt)
set(FOO 123 CACHE STRING "demo variable")
  • 写入CMakeCache.txt

  • 下次 cmake 直接读取

  • 用户可通过-D修改

3️⃣FORCE的影响
set(CMAKE_CXX_FLAGS "... " CACHE STRING "" FORCE)
  • 强制覆盖 cache

  • 用户无法修改

  • 常见于老项目(技术债)

(5)、生命周期对比

项目CMakeLists.txtCMakeCache.txt
谁创建人写CMake 自动生成
是否可版本管理✔️ 是❌ 否
是否可删除✔️(安全)
是否参与逻辑✔️
是否保存状态✔️
修改是否推荐✔️

(6)、最常见误区

❌ 误区 1:改了 CMakeLists.txt,但结果没变

原因:值已在CMakeCache.txt中存在;被 cache 覆盖

解决:rm -rf build && cmake ..

❌ 误区 2:改 cache 当改源码

直接编辑CMakeCache.txt

  • 短期“好像有用”

  • 下次 cmake 可能被覆盖

  • 不可维护

❌ 误区 3:不知道编译器“被锁死”了

一旦第一次配置选择了编译器:CMAKE_CXX_COMPILER=/usr/bin/g++

后续:CC=clang CXX=clang++ cmake ..

👉无效,除非清 cache

(7)、工程实践总结

  1. CMakeLists.txt 是规则,必须可读、可维护

  2. CMakeCache.txt 是状态,可删不可改

  3. 遇到“CMake 怎么都不生效”:删 build 目录

  4. 不要在 CMakeLists.txt 里滥用:set(... CACHE ... FORCE)

CMakeLists.txt 决定“应该怎么构建”,
CMakeCache.txt 记录“这次到底怎么构建了”。


四、CMakeLists实例

一、示例项目目录结构

my_project/ ├── CMakeLists.txt # 顶层 ├── cmake/ │ └── toolchain-clang.cmake # 可选 ├── src/ │ ├── main.cpp │ ├── math/ │ │ ├── add.cpp │ │ └── add.h │ └── CMakeLists.txt ├── include/ │ └── my_project/ │ └── config.h ├── tests/ │ ├── test_add.cpp │ └── CMakeLists.txt └── README.md

二、顶层CMakeLists.txt核心文件

cmake_minimum_required(VERSION 3.16) # 1️⃣ 项目定义 project( MyProject VERSION 1.0.0 LANGUAGES C CXX ) # 2️⃣ C++ 标准(全局约束,不是 flags) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) # 3️⃣ 常用构建选项 option(ENABLE_TESTS "Build tests" ON) option(ENABLE_WARNINGS "Enable compiler warnings" ON) # 4️⃣ 编译器相关设置(只放“安全判断”) if (ENABLE_WARNINGS) if (MSVC) add_compile_options(/W4) else() add_compile_options(-Wall -Wextra -Wpedantic) endif() endif() # 5️⃣ 添加子目录 add_subdirectory(src) if (ENABLE_TESTS) enable_testing() add_subdirectory(tests) endif()

三、src/CMakeLists.txt(业务代码)

# 1️⃣ 创建库(推荐:先库后程序) add_library(my_math math/add.cpp ) # 2️⃣ 头文件路径(PUBLIC 会传递) target_include_directories(my_math PUBLIC ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/src ) # 3️⃣ 编译特性(比 set(CMAKE_CXX_STANDARD) 更精细) target_compile_features(my_math PUBLIC cxx_std_17) # 4️⃣ 可执行程序 add_executable(my_app main.cpp ) # 5️⃣ 链接库 target_link_libraries(my_app PRIVATE my_math )

四、tests/CMakeLists.txt(单元测试)

add_executable(test_add test_add.cpp ) target_link_libraries(test_add PRIVATE my_math ) add_test( NAME test_add COMMAND test_add )

五、示例源码(最小可跑)

src/main.cpp

#include <iostream> #include "math/add.h" int main() { std::cout << add(2, 3) << std::endl; return 0; }

src/math/add.h

#pragma once int add(int a, int b);

src/math/add.cpp

#include "math/add.h" int add(int a, int b) { return a + b; }

六、构建方式

mkdir build cd build cmake .. \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_CXX_COMPILER=clang++ cmake --build . ctest

七、这个示例里“正确做了什么”

✅ 1️⃣ 没有使用CMAKE_CXX_FLAGS

# ❌ 没有 set(CMAKE_CXX_FLAGS "...") # ✅ 使用 target_compile_options() target_compile_features()

✅ 2️⃣ 库 / 可执行分离

  • 业务逻辑 →add_library

  • 程序入口 →add_executable

这是大型项目必备结构

✅ 3️⃣ include 目录是 target 级别

target_include_directories(my_math PUBLIC ...)

不会污染全局

✅ 4️⃣ 测试是可选的

option(ENABLE_TESTS ON)

适合 CI / Release 裁剪

八、一个“反例”

❌ 不推荐的 CMakeLists:

set(CMAKE_CXX_FLAGS "-std=c++11 -O2") include_directories(include) link_libraries(mylib)

原因:全局污染;不可维护;多 target 会炸

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 12:29:27

有源与无源蜂鸣器区别:时序控制原理图解说明

以下是对您提供的博文内容进行 深度润色与专业重构后的版本 。整体遵循“去AI化、强工程感、重逻辑流、轻模板化”的原则,摒弃所有程式化标题与刻板结构,以一位资深嵌入式硬件工程师在技术分享会上娓娓道来的口吻展开叙述。全文聚焦真实开发场景中的痛点、决策依据与落地细…

作者头像 李华
网站建设 2026/4/15 15:04:24

教育行业福音:自动检测试卷文字区域的AI工具

教育行业福音&#xff1a;自动检测试卷文字区域的AI工具 在教育数字化转型过程中&#xff0c;教师每天要面对大量试卷批改、成绩录入和错题分析工作。其中最耗时的环节之一&#xff0c;就是从扫描件或拍照图片中手动框选题目、学生作答区域、分数栏等关键文字区域——这个过程…

作者头像 李华
网站建设 2026/4/16 12:35:50

Qwen3-14B部署内存泄漏?监控与调优实战解决方案

Qwen3-14B部署内存泄漏&#xff1f;监控与调优实战解决方案 1. 问题真实存在&#xff1a;不是幻觉&#xff0c;是显存“悄悄蒸发” 你刚用 ollama run qwen3:14b 启动模型&#xff0c;WebUI 显示一切正常——GPU 利用率 35%&#xff0c;显存占用 18.2 GB。 可当你连续处理 5 …

作者头像 李华
网站建设 2026/4/18 0:07:39

Qwen-Image-Layered在电商设计中的应用,效率翻倍

Qwen-Image-Layered在电商设计中的应用&#xff0c;效率翻倍 1. 为什么电商设计师需要图层化编辑能力 你有没有遇到过这样的情况&#xff1a;刚做完一张主图&#xff0c;运营突然说“把模特换成穿新季款式的”&#xff0c;或者“背景换成纯白&#xff0c;但保留阴影细节”&am…

作者头像 李华
网站建设 2026/3/11 7:09:33

Colab免费资源跑Qwen3-0.6B,性价比超高

Colab免费资源跑Qwen3-0.6B&#xff0c;性价比超高 在大模型门槛依然较高的今天&#xff0c;能用零成本跑通一个真正可用的开源大模型&#xff0c;是很多开发者梦寐以求的事。Qwen3-0.6B作为千问系列最新发布的轻量级密集模型&#xff0c;参数仅0.6B&#xff0c;却完整继承了Q…

作者头像 李华
网站建设 2026/4/17 3:52:24

BERT模型推理延迟高?免配置镜像一键部署实战解决

BERT模型推理延迟高&#xff1f;免配置镜像一键部署实战解决 1. 为什么BERT填空总卡顿&#xff1f;真实痛点拆解 你是不是也遇到过这样的情况&#xff1a;想用BERT做中文语义填空&#xff0c;本地跑起来却慢得让人抓狂&#xff1f;输入一句话&#xff0c;等三五秒才出结果&am…

作者头像 李华