news 2026/6/26 4:01:32

Cmake 基础用法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cmake 基础用法

# ==================================================
# CMake 学习项目 - 一个文件搞懂核心语法
# ==================================================
# 编译方法:
# cd code
# mkdir build; cd build
# cmake ..
# make
# ./hello

#

# cmake .. → 读取上一级(../)的 CMakeLists.txt,在当前目录生成 Makefile

# make → 读取当前目录的 Makefile,执行编译

# 关闭某个功能试试:
#cmake -DENABLE_LOG=OFF ..
# ==================================================

# ---- [知识点1] 项目声明 ----
cmake_minimum_required(VERSION 3.10) # 当前cmake 要求的最低 版本号
project(cmake_learn C) # 自定义项目名 + 源码后缀如果有C++ , C后面要加CPP

# ---- [知识点2] option: 开关选项(类比 Kconfig) ----
option(ENABLE_LOG "启用日志功能" ON) # 如果不指定默认cmake 变量开关的值,
option(ENABLE_MATH "启用数学模块" ON) #如果指定可以 cmake

# ---- [知识点3] set: 定义变量 ----
set(APP_VERSION "1.0.0")
message(STATUS "版本: ${APP_VERSION}")
message(STATUS "日志: ${ENABLE_LOG}")
message(STATUS "数学: ${ENABLE_MATH}")

# ---- [知识点4] 收集源文件 ----
# main.c 始终编译
set(SOURCES main.c)

# 根据 option 决定是否加入 utils.c(类比 obj-$(CONFIG_X) += xxx.o)
if(ENABLE_LOG)
list(APPEND SOURCES utils.c)
endif()

if(ENABLE_MATH)
list(APPEND SOURCES calc.c)
endif()

# ---- [知识点5] add_executable: 编译可执行文件 ----
add_executable(hello ${SOURCES})

# ---- [知识点6] target_compile_definitions: 添加宏定义 ----
target_compile_definitions(hello PRIVATE APP_VERSION="${APP_VERSION}")

if(ENABLE_LOG)
target_compile_definitions(hello PRIVATE HAS_LOG)
endif()

if(ENABLE_MATH)
target_compile_definitions(hello PRIVATE HAS_MATH)
endif()

# ---- [知识点7] target_compile_options: 编译选项 ----
target_compile_options(hello PRIVATE -Wall)

# ---- [知识点8] add_library: 静态库 ----
add_library(mylib STATIC sensor.c)
target_link_libraries(hello PRIVATE mylib)

--------------------------------------------------------------------------------------------------------

ubuntu@WIN-07G84A33SUO:/mnt/e/Qoder/Cmake/build$ cmake ..
-- The C compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- 版本: 1.0.0
-- 日志: ON
-- 数学: ON

-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/e/Qoder/Cmake/build

------------------------------------------------------------------------------------------

Scanning dependencies of target mylib
[ 16%] Building C object CMakeFiles/mylib.dir/sensor.c.o
[ 33%] Linking C static library libmylib.a
[ 33%] Built target mylib
Scanning dependencies of target hello
[ 50%] Building C object CMakeFiles/hello.dir/main.c.o
[ 66%] Building C object CMakeFiles/hello.dir/utils.c.o
[ 83%] Building C object CMakeFiles/hello.dir/calc.c.o
[100%] Linking C executable hello
[100%] Built target hello

------------------------------------------------------------------------------------------

CMake 帮你把这些参数自动分配给每个源文件,不用自己一个个写。

CMake 指令类比内核 Makefile
target_compile_definitions(hello PRIVATE HAS_LOG)ccflags-y += -DHAS_LOG
target_compile_options(hello PRIVATE -Wall)ccflags-y += -Wall
target_link_libraries(hello PRIVATE mylib)ldflags-y += -lmylib

核心理解

CMake 就是一个 Makefile 生成器

CMakeLists.txt (你写的)

│ cmake ..

Makefile + flags.make + link.txt (自动生成的)

│ make

hello (可执行文件)

你写的 CMakeLists.txt 是高层描述,cmake 翻译成底层 Makefile 规则。如果你手写 Makefile,就等于自己写C_FLAGS = -Wall -Dxxx这些;用 CMake 就是让它帮你自动生成,而且跨平台(Windows/Linux 都能生成对应的构建文件)。

-------------------------------------------------------------------------------------------------------------

实际编译命令

make 编译main.c时,实际执行的是:

gcc -Wall -DAPP_VERSION=\"1.0.0\" -DHAS_LOG -DHAS_MATH -c main.c -o main.o │ │ │ │ │ │ │ │ │ └─ 编译哪个文件 │ │ │ └─ C_DEFINES │ │ └─ C_DEFINES │ └─ C_FLAGS

逐个解释

变量gcc 参数作用具体效果
C_FLAGS-Wall-Wall开启所有常见警告有潜在问题代码时打印警告,不中断编译
C_DEFINES-DAPP_VERSION=\"1.0.0\"-D定义宏,传值C 代码里APP_VERSION变成"1.0.0"
C_DEFINES-DHAS_LOG-D定义宏,只定义C 代码里#ifdef HAS_LOG为真
C_DEFINES-DHAS_MATH-D定义宏,只定义C 代码里#ifdef HAS_MATH为真
C_INCLUDES(空)-I指定头文件搜索路径当前为空,用默认路径

实际效果对比

-Wall的作用:

// 没有 -Wall:编译通过,不提示

// 有 -Wall:编译时会打印警告

int x;

printf("%d", x); // 警告:变量 x 未初始化就使用了

-D有值 vs 无值的区别:

// -DAPP_VERSION=\"1.0.0\" → 有值,可以当字符串用

printf("版本: %s\n", APP_VERSION); // 输出:版本: 1.0.0

// -DHAS_LOG → 无值,只表示"已定义"

#ifdef HAS_LOG

log_print("日志已启用"); // 这段代码会被编译

#endif

-I头文件路径(当前为空):

# 如果有这一行: target_include_directories(hello PRIVATE /opt/mylib/include)
# C_INCLUDES 就会变成: C_INCLUDES = -I/opt/mylib/include

这样#include "xxx.h"时,gcc 会去那个目录找头文件。你现在项目头文件都在同目录,所以不需要。

----------------------------------------------------------------

最终可以执行

ubuntu@WIN-07G84A33SUO:/mnt/e/Qoder/Cmake/build$./hello
=== CMake 学习 Demo (v1.0.0) ===
[LOG] 日志功能已启用
add(3, 5) = 8
mul(4, 7) = 28
温度: 25.6 C (来自静态库 mylib)

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

郎月婷张天阳李卿主演,软科幻悬疑剧《幻世》6月25日登陆优酷

近日,由赵凯担任导演/编剧/制片人,领衔主演郎月婷、张天阳、李卿,特别主演王放,特邀出演吴启华、彭杨,特别出演孔琳、施羽、赵倩、王艺禅、陈冠甯,友情出演许佳琪、刘凯、常荻、钱迪迪、何廖侣匀联袂打造的…

作者头像 李华
网站建设 2026/6/26 4:00:19

linux安装达梦数据库

安装达梦数据库: groupadd dinstall useradd dmdba -g dinstall mount -t loop /mnt/iso dm.iso su - dmdba # 先设置一个解压目录,必须到与2G export DM_INSTALL_TMPDIR/home/dmdba/tmp # 安装达梦辅助插件 /data/iso/DMInstall.bin -i安装完成后注册辅…

作者头像 李华
网站建设 2026/6/26 3:59:54

MMIO 和 PCIe 3.0 / 10G/100G 网口的完整关系梳理

MMIO 和 PCIe 3.0 / 10G/100G 网口的完整关系梳理 一、先分清两个概念本质 1. MMIO(内存映射 IO) 是CPU 访问外设的寻址模型,属于软件 / 总线地址层面规范; CPU 把外设寄存器映射到物理地址空间,用读写内存指令操控硬件…

作者头像 李华
网站建设 2026/6/26 3:58:38

FPGA高精度TDC设计:POR与ITI技术解析

1. FPGA高精度TDC设计背景与挑战在量子通信、激光雷达(LiDAR)和核物理实验等领域,皮秒级时间测量精度已成为关键需求。传统的时间-幅度转换器(TAC)虽然精度较高,但其模拟特性导致集成难度大、测量范围有限。相比之下,时间数字转换器(TDC)凭借…

作者头像 李华
网站建设 2026/6/26 3:58:17

基于ESP32的智能声光控照明系统:从原理到实践

1. 项目概述:从“声光控”到“智能照明”的进化几年前,我还在为一个老旧小区的楼道灯改造项目头疼。传统的声光控开关虽然解决了“人来灯亮,人走灯灭”的基本需求,但问题一大堆:深夜一点声响就亮灯扰民、阴天光线稍暗就…

作者头像 李华
网站建设 2026/6/26 3:57:33

从CTF实战解析SQL注入:过滤绕过与堆叠注入攻防

1. 从一道经典CTF题看SQL注入的攻防博弈最近在复盘一些经典的网络安全竞赛题目,发现“[极客大挑战 2019]easysql”这道题被反复提及,甚至衍生出“[suctf 2019]easysql”等多个变种。题目名字叫“easysql”,听起来简单,但里面蕴含的…

作者头像 李华