尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Cmake 基础用法

Cmake 基础用法
📅 发布时间:2026/6/26 4:16:29

# ==================================================
# 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)

相关新闻

  • 036、SPIR-V Dialect:GPU Shader与Vulkan生态
  • 如何用Python工具为Beyond Compare 5生成有效授权密钥?3种方法全解析
  • 35-页面模板组织与前后端协作方式:平台如何把模块能力落到可维护页面

最新新闻

  • 【C/C++】select、poll、epoll 实战对比:从 fd_set 到就绪事件列表
  • 云手机不只是挂机:ARM 虚拟化架构 + ADB 自动化实战,附完整代码
  • 从 0 到 1 搭建 NexusAgent
  • MongoDB入门实战:从核心概念到CRUD操作与索引优化
  • 终极音乐解锁指南:3分钟掌握15+加密格式解密技巧
  • 20VOUT,9W,XL2170,恒压限流LED升压驱动芯片

日新闻

  • Qwen2.5-Turbo百万上下文实战指南:百炼平台长文本处理全解析
  • 怎么监控对标账号更新,2026年作者监控工作流,5款深度对比
  • EdgeRemover:专业级Windows Edge浏览器管理工具,彻底解决顽固软件卸载难题

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号