news 2026/4/16 16:00:26

【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:34:30

IQuest-Coder-V1-40B-Instruct参数详解:部署前必看优化指南

IQuest-Coder-V1-40B-Instruct参数详解&#xff1a;部署前必看优化指南 1. 这不是普通代码模型&#xff0c;而是专为真实开发场景打磨的“工程型助手” 你可能已经用过不少代码大模型——输入几行注释&#xff0c;生成函数&#xff1b;贴一段报错&#xff0c;给出修复建议。但…

作者头像 李华
网站建设 2026/4/16 13:36:56

快速理解LVGL中layer分层渲染的工作模式

以下是对您提供的博文内容进行 深度润色与结构重构后的技术文章 。整体风格已全面转向 资深嵌入式GUI工程师第一人称实战分享口吻 ,彻底去除AI生成痕迹、模板化表达和空泛总结;所有技术点均以“我踩过的坑”“我们实测的数据”“手册里没明说但实际必须注意的细节”等真实…

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

BERT能否理解古诗词?‘床前明月光’填空实战测试

BERT能否理解古诗词&#xff1f;‘床前明月光’填空实战测试 1. 什么是BERT智能语义填空服务 你有没有试过在读古诗时&#xff0c;突然卡在一个字上——明明知道下一句该是什么&#xff0c;却一时想不起来&#xff1f;或者看到半句“春风又绿江南岸”&#xff0c;下意识想补全…

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

FSMN VAD快速上手:微信开发者支持部署入门必看

FSMN VAD快速上手&#xff1a;微信开发者支持部署入门必看 1. 为什么你需要这个语音检测工具&#xff1f; 你有没有遇到过这些场景&#xff1f; 会议录音长达两小时&#xff0c;但真正有用的发言只占30%&#xff0c;手动剪辑耗时又容易漏掉关键内容&#xff1b;电话客服录音…

作者头像 李华
网站建设 2026/4/16 13:31:09

为什么选SGLang?对比6大框架后的答案

为什么选SGLang&#xff1f;对比6大框架后的答案 在大模型落地的实战一线&#xff0c;我们常被一个问题反复拷问&#xff1a;不是已经有vLLM、TensorRT-LLM这些成熟框架了吗&#xff1f;为什么还要多学一个SGLang&#xff1f; 这不是技术堆砌的冗余选择&#xff0c;而是面向真…

作者头像 李华
网站建设 2026/4/16 9:09:04

解决Multisim主数据库访问问题的完整指南

以下是对您提供的博文内容进行 深度润色与结构化重构后的技术文章 。全文已彻底去除AI生成痕迹,采用真实工程师口吻写作,逻辑更连贯、语言更精炼、教学性更强,并严格遵循您提出的全部优化要求(无模板化标题、无总结段落、不使用“首先/其次”类连接词、融合经验判断与实操…

作者头像 李华