CMAKE备忘录

目录

[CMake 是什么?](#CMake 是什么?)

1.set()

[2.file() 用于 文件和目录操作](#2.file() 用于 文件和目录操作)

[1. 查找文件(最常用)](#1. 查找文件(最常用))

[查找 .cpp 文件](#查找 .cpp 文件)

递归查找

[2. 读取文件](#2. 读取文件)

[3. 写文件](#3. 写文件)

[4. 复制文件](#4. 复制文件)

[5. 创建目录](#5. 创建目录)

[6. 删除文件](#6. 删除文件)

[7. 获取绝对路径](#7. 获取绝对路径)

常用场景

自动添加源码

复制配置文件

常用命令总结

3.add_definitions


CMake 是什么?

CMakeMakefilemakegcc 的关系,可以理解成一个编译工程的流水线:

大型项目不喜欢手写 Makefile。

比如 Linux 内核、Qt、OpenCV 这种项目,有很多,手写 Makefile 很痛苦。

复制代码
src/
include/
lib/
test/
third_party/

简单说:

  • gcc:真正负责"编译代码"的工具
  • make:负责"按照规则自动执行编译命令"
  • Makefile:告诉 make "应该怎么编译"
  • CMake:负责"生成 Makefile(或者其他构建系统文件)"
命令 作用
cmake_minimum_required 指定CMake版本
project 定义工程
set 定义变量
add_executable 生成程序
add_library 生成库
target_include_directories 添加头文件
target_link_libraries 链接库
target_compile_options 添加编译参数
target_compile_definitions 添加宏
file 文件操作
find_package 查找第三方库
add_subdirectory 添加子目录
install 安装
if 条件判断

1.set()

创建变量、修改变量、保存路径、保存文件列表、设置 CMake 参数等。

基本格式:

复制代码
set(变量名 值)

例如:

复制代码
set(NAME hello)

表示:

复制代码
创建变量 NAME
值为 hello

使用:

复制代码
message(${NAME})

2.file() 用于 文件和目录操作

  • 查找源码文件
  • 创建目录
  • 复制文件
  • 读取/写入文件
  • 获取路径等

基本格式:

复制代码
file(操作 参数...)

1. 查找文件(最常用)

查找 .cpp 文件

复制代码
file(
    GLOB SRC
    *.cpp
)

说明:

复制代码
GLOB  → 匹配文件
SRC   → 保存结果的变量
*.cpp → 查找规则

使用:

复制代码
add_executable(
    app
    ${SRC}
)

递归查找

复制代码
file(
    GLOB_RECURSE SRC
    src/*.cpp
)

查找:

复制代码
src/
├── main.cpp
└── lib/test.cpp

都会找到。


2. 读取文件

复制代码
file(
    READ
    version.txt
    VERSION
)

message(${VERSION})

作用:读取 version.txt 内容保存到变量 VERSION


3. 写文件

复制代码
file(
    WRITE
    test.txt
    "hello cmake"
)

生成:

复制代码
test.txt

内容:

复制代码
hello cmake

4. 复制文件

复制代码
file(
    COPY
    config/    //源目录
    DESTINATION //目的地
    ${CMAKE_BINARY_DIR}
)

//${CMAKE_BINARY_DIR} 是 CMake 固定定义的内置变量名,不是你自己随便起的。

CMake 在运行时会自动创建这些变量,你可以直接使用:

message(${CMAKE_BINARY_DIR})

CMake 会打印当前构建目录。

作用:

复制代码
config/
    |
    v
build目录

5. 创建目录

复制代码
file(
    MAKE_DIRECTORY
    build/log
)

相当于:

复制代码
mkdir -p build/log

6. 删除文件

复制代码
file(
    REMOVE
    test.txt
)

7. 获取绝对路径

复制代码
file(
    REAL_PATH
    ./test.txt
    PATH
)

message(${PATH})

常用场景

自动添加源码

复制代码
file(
    GLOB SRC
    src/*.cpp
)
/*
file(GLOB_RECURSE SRC_User CONFIGURE_DEPENDS ${USR_DIR}/*.c ${USR_DIR}/*.h)
告诉 CMake:以后如果 GLOB 查找出来的文件列表发生变化,自动重新运行 CMake 配置。

它主要用于解决 file(GLOB) 自动查找源码时,新文件加入的问题。
*/
add_executable(
    app
    ${SRC}
)

复制配置文件

复制代码
file(
    COPY
    config.ini
    DESTINATION
    ${CMAKE_BINARY_DIR}
)

常用命令总结

命令 作用
file(GLOB) 查找文件
file(GLOB_RECURSE) 递归查找
file(READ) 读取文件
file(WRITE) 写文件
file(COPY) 复制文件
file(MAKE_DIRECTORY) 创建目录
file(REMOVE) 删除文件
file(REAL_PATH) 获取绝对路径

3.add_definitions

复制代码
add_definitions(-D__ARM_ARCH_PROFILE='M'),等价于: gcc -DNAME=value add_definitions( -D宏名=值 )

add_definitions() 没有目标名,因为它是全局添加编译定义;而 target_compile_definitions() 是针对某个 target 添加定义**。**

现代 CMake 推荐替代:

复制代码
# 只对指定目标添加宏

target_compile_definitions(
    目标名
    PRIVATE
    宏名
)

1. 目标名(target)

这里的目标就是你之前创建的:add_executable()或者:add_library()生成的东西。

例如:

# 创建一个可执行程序,名字叫 app
add_executable(
    app
    main.cpp
)

这里:app就是一个 target(目标)。

然后:

target_compile_definitions(
    app
    PRIVATE
    DEBUG
)

意思:给 app 这个目标添加 DEBUG 宏

等价:

gcc main.cpp -DDEBUG

2. PRIVATE 是什么?

PRIVATE 表示:

这个宏只给当前目标使用,不传递给依赖它的其他目标。

例如:

复制代码
target_compile_definitions(
    app
    PRIVATE

    DEBUG
    STM32F10X_HD
)

等价:

复制代码
gcc -DDEBUG -DSTM32F10X_HD
相关推荐
波特率11520011 小时前
pthread库函数解析
linux·线程·pthread
Escalating_xu11 小时前
【Linux线程同步】从数据竞争到 mutex、条件变量与生产者消费者(上篇)
android·java·linux
晨曦花锦11 小时前
Vim基础操作与Ollama模型管理,顺便配置Nginx反向代理
linux·nginx·编辑器·vim
Eloudy11 小时前
Ubuntu 22.04 从源码编译安装 ROS 2 Jazzy 笔记
linux·笔记·ubuntu
运维行者_11 小时前
预测性云监控怎么做?AI驱动的7大核心能力与落地路径
服务器·开发语言·网络·数据库·人工智能·python·php
赋创小助手11 小时前
机器人研发负载拆解:数据、仿真、训练与推理分别需要哪些计算资源?
服务器·人工智能·机器人·具身智能·gpu计算
raindayinrain11 小时前
深入理解Linux内核-页表,TLB,高速缓存,性能优化
linux·性能优化·高速缓存·页表·tlb
阿沐沐,12 小时前
PowerShell 里改了 config.toml,Codex CLI 仍用旧值:先分清该改哪一层
java·服务器·数据库·人工智能·ai·ai编程
秣宇12 小时前
银河麒麟服务器操作系统关闭 Swap 分区
linux·运维·服务器·github·kylin