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 是什么?

CMake、Makefile、make 和 gcc 的关系,可以理解成一个编译工程的流水线:

大型项目不喜欢手写 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
相关推荐
say_fall32 分钟前
【Linux网络编程】UDP套接字编程:系统编程组件、基础回显服务、InetAddr与地址转换、翻译服务与线程池聊天室
linux·服务器·网络·udp·vr
ö Constancy1 小时前
一台电脑的硬件组成与作用:按功能分类详解(Windows 与 Linux 视角)
linux·windows·电脑
江湖有缘1 小时前
基于Ubuntu部署SoduWork:企业级 AI 原生协同平台实战全流程
linux·人工智能·ubuntu·ai·soduwork
无奈笑天下10 小时前
银河麒麟上nproc命令教程详解
linux·运维·服务器
Rabitebla13 小时前
【Linux】进程控制(十二) 自定义 Shell(二):内建命令与进程工作目录管理
linux·c++·笔记·学习·bash
火云代理13 小时前
更换网络后为什么会退出登录?分清 IP、Cookie 与会话的关系
服务器·网络·网络协议·tcp/ip·php·ip
威嵌神州14 小时前
嵌入式排故实录:高并发下串口数据“超时丢包”的根因剖析与架构优化
运维·服务器·嵌入式硬件·缓存
Decay__15 小时前
SQLServer 索引与 SQL 优化 —— 聚集索引、非聚集索引、覆盖索引、碎片维护与执行计划
运维·数据库·sql·mysql·架构
java_logo15 小时前
Docker 部署 DeepSeek Harness(moelin):轻松搭建带登录的本地 AI Agent 平台
运维·docker·容器·ai agent·deepseek·harness·轩辕镜像
火云代理17 小时前
同一个网站,有的网络能打开、有的打不开?认识 IPv4 与 IPv6 的访问差异
服务器·网络·网络协议·tcp/ip·测试工具·php·状态模式