Cmake 基础用法

📅 2026/6/26 4:01:45
Cmake 基础用法
# # CMake 学习项目 - 一个文件搞懂核心语法# # 编译方法:# cd code# mkdir build; cd build# cmake ..# make# ./hello## cmake .. → 读取上一级(../)的 CMakeLists.txt在当前目录生成 Makefile# make → 读取当前目录的 Makefile执行编译# 关闭某个功能试试:#cmake -DENABLE_LOGOFF ..# # ---- [知识点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.oif(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)--------------------------------------------------------------------------------------------------------ubuntuWIN-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 mylibScanning 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 指令类比内核 Makefiletarget_compile_definitions(hello PRIVATE HAS_LOG)ccflags-y -DHAS_LOGtarget_compile_options(hello PRIVATE -Wall)ccflags-y -Walltarget_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.0C_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_LOGlog_print(日志已启用); // 这段代码会被编译#endif-I头文件路径当前为空# 如果有这一行 target_include_directories(hello PRIVATE /opt/mylib/include)# C_INCLUDES 就会变成 C_INCLUDES -I/opt/mylib/include这样#include xxx.h时gcc 会去那个目录找头文件。你现在项目头文件都在同目录所以不需要。----------------------------------------------------------------最终可以执行ubuntuWIN-07G84A33SUO:/mnt/e/Qoder/Cmake/build$./hello CMake 学习 Demo (v1.0.0) [LOG] 日志功能已启用add(3, 5) 8mul(4, 7) 28温度: 25.6 C (来自静态库 mylib)