Cmake的基础用法
1. 什么是Cmake解决了什么问题当仅有一个源文件是如main.c仅采用gcc即可编译成可执行文件。但一个工程中有成千上万的源文件此时就有了makefile的出现。但又有问题出现了--不同平台的makefile语法、格式不一样这就导致软件想跨平台使用时每次都要根据新的平台编写一次makefile极其麻烦。针对上述问题引入了Cmake。它是一种跨平台工具允许开发者编写与平台无关的CMakeLists.txt文件来制定整个 工程的编译流程再根据具体的编译平台生成本地化的Makefile和工程文件最后执行make编译即Cmake就是生成makefile的工具。2. Cmake的使用方法下边从单源文件编译和不同目录下的多源文件编译两方面来介绍如何使用Cmake搭建编译环境。前提先在Linux环境下安装好Cmake、gcc、g不要忘记装如果没检测到cmake编译会报错。2.1 单源文件编译首先在某个工程文件夹下创建两个文件CmakeLists.txt以及main.c假设是一个hello world程序下边编辑CmakeLists.txt文件如下图所示# 不强制要求写此行代码但最好加上表示Cmake的最低版本要求 cmake_minimum_required(VERSION 3.16) # 表示项目信息括号里边的是自定义的项目名 project(Pro) # 表示生成一个可执行文件有两个参数main代表可执行文件名字 #main.c代表源文件 add_executable(main main.c)编辑完后保存然后在当前工程文件夹所在目录下打开终端执行命令如下# -S代表源代码目录-B代表指定构建目录build如果没有会创建 # 使用此命令代表在build目录下生成makefile cmake -S . -B build # 使用此命令代替make仅需在工程目录下即可使用 # 好处是跨平台能自动生成对应平台的编译工具 cmake --build build即可得到可执行文件main但此时会发现该工作区目录下还会存在很多Cmake的中间文件如下图所示这些文件与可执行文件以及源文件混淆在一起看着很不美观因此可以在工作区目录下再创建一个build文件夹创建好之后进入buiild文件夹cd build/然后再执行下述命令# -S代表源代码目录-B代表指定构建目录build如果没有会创建 # 使用此命令代表在build目录下生成makefile cmake -S . -B build # 使用此命令代替make仅需在工程目录下即可使用 # 好处是跨平台能自动生成对应平台的编译工具 cmake --build build即可将生成的cmake中间文件都保存在build文件夹下了。2.2 多目录多个源文件编译在真实开发环境中我们的代码工程肯定不止一个源文件因此采用的是模块化编程的思想将多个源文件存放在不同的目录在这种情况下Cmake的编译环境搭建目录架构如下图所示可以看到在每一层目录下都有一个CmakeLists.txt文件。接下来需要编辑每一层目录下的CmakeLists.txt文件。顶层Cmake# 版本号要求 cmake_minimum_required(VERSION 3.16) # 项目名 project(HELLO) # 表示告诉Cmake去子目录寻找新的CmakeLists.txt文件进行解析 add_subdirectory(libary) # 去src目录下寻找CmakeLists.txt文件解析 add_subdirectory(src)libhello目录下Cmake# set命令用于设置变量此处表示改编库文件的输出路径为build/lib set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) # 表示添加库文件libhello为库文件夹名SHARED代表生成的是动态库文件 #以.so结尾STATIC是静态库文件以.a结尾 add_library(libhello SHARED hello.c) # 该命令是改变生成的库文件名 #因为最终生成的库文件名会包含前缀lib和后缀.so如果不加下述命令就会 #编程liblibhello.so不美观加了下述命令就会变成libxx.so set_target_properties(libary PROPERTIES OUTPUT_NAME xx)src目录下Cmake# 该命令用来指明头文件所在的路径并且使用到了PROJECT_SOURCE_DIR变量 # 该变量指向了一个路径表示工程源码的目录 include_directories(${PROJECT_SOURCE_DIR}/libhello) # 改变可执行文件的输出路径在build/bin文件目录下 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) # 生成可执行文件hello add_executable(hello main.c) # 链接库文件 target_link_libraries(hello libhello)一切就绪后进入build文件夹运行下述命令# -S代表源代码目录-B代表指定构建目录build如果没有会创建 # 使用此命令代表在build目录下生成makefile cmake -S . -B build # 使用此命令代替make仅需在工程目录下即可使用 # 好处是跨平台能自动生成对应平台的编译工具 cmake --build build即可得到可执行文件hello。如果libhello下的目录结构再改一下hello.c保存在libhello/src下hello.h保存在libhello/inc文件夹下此时的CmakeLists.txt要改写为# 设置库文件输出路径 set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) # 获取当前目录下的src文件夹下的所有.c文件 file(GLOB LIB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.c) # 添加成动态库文件 add_library(libhello SHARED ${LIB_SOURCES}) # 指定 libhello/inc/ 为头文件目录PUBLIC 意味着链 # 接此库的目标如 main也能自动找到这些头文件 target_include_directories(libhello PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc) # 改变生成的库文件名字为libxx.so否则为liblibhello.so set_target_properties(libhello PROPERTIES OUTPUT_NAME xx)Notetarget_include_directories(命令中用了一个关键字PUBLIC表示如果下游的文件main.c要使用到hello.c里边的功能时需要加关键字PUBLIC如果不用需要将关键字改为PRIVATE。总结来说有这几种权限private代表仅对当前目标有效public对当前目标和链接它的目标都有效interface仅对链接它的目标有效。2.3 target_compile_definitions命令该命令用于向指定的目标库添加预处理器比如# 用于向指定目标vision_command_line库添加预处理器在编译时该定义会被编译器识别为#define XXX # private代表仅对当前目标有效public对当前目标和链接它的目标都有效interface仅对链接它的目标有效 # 宏名为 VISION_DEFAULT_RECIPE_PATH值为${VISION_RECIPE_PATH} target_compile_definitions( vision_command_line PRIVATE VISION_DEFAULT_RECIPE_PATH${VISION_RECIPE_PATH} )上图表示在指定的目标库vision_comman_line中添加预处理器当编译时会被编译器识别成#define VISION_DEFAULT_RECIPE_PATH ${VISION_RECIPE_PATH};后边代表宏的值这是变量可以任意改变。这样做的好处是如果要修改宏VISION_DEFAULT_RECIPE_PATH的值只需要在CMakeLists.txt中修改即可无需修改代码本身提高了灵活性和可维护性。2.4 add_library命令这个命令代表添加库的意思其实就是把c/cpp文件链接成一个库文件举例add_library(vision_capture src/camera/v4l2_camera_provider.cpp )上述就是将xxx.cpp添加成库文件vision_capture。2.5 target_include_directories命令一个源文件必然有与之配套的头文件因此这个命令用于链接相应的头文件用法如下target_include_directories(vision_capture PUBLIC src include ${OpenCV_INCLUDE_DIRS})2.6 target_link_libraries命令该命令用于链接库比如a.c文件中调用了b.c文件定义的函数那么就需要用这个命令来添加依赖关系target_link_libraries(vision_capture PUBLIC vision_data ${OpenCV_LIBS})3. 总结本篇文章笔者仅讲解了Cmake的基础用法。实际上Cmake还有很多语法和格式包括函数、条件、循环等大家在用到时再自行琢磨。

相关新闻

非随机场景下的因果推断实战:DiD、OLS与贝叶斯归因框架

非随机场景下的因果推断实战:DiD、OLS与贝叶斯归因框架

1. 为什么你手头的“效果评估”可能正在悄悄失效 你刚上线了一版新的用户注册流程,埋点数据显示次日留存率涨了2.3%;市场团队发了一轮定向邮件,转化率报表上跳出了1.4%的箭头;临床团队给一批患者用了新药方案,30天复发…

2026/10/16 14:55:40 阅读更多 →
Unity UGUI虚拟键盘开发指南:从架构设计到移动端优化

Unity UGUI虚拟键盘开发指南:从架构设计到移动端优化

1. 项目概述:为什么我们需要自制虚拟键盘? 在Unity开发移动端或触屏应用时,系统软键盘(System Keyboard)是个让人又爱又恨的存在。爱它,是因为它开箱即用,无需额外开发;恨它&#xf…

2026/10/17 1:39:00 阅读更多 →
抖音批量下载神器:3分钟掌握高效素材收集的终极指南

抖音批量下载神器:3分钟掌握高效素材收集的终极指南

抖音批量下载神器:3分钟掌握高效素材收集的终极指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support…

2026/10/18 22:17:50 阅读更多 →

最新新闻

MCP协议深度解析:从设计思路到实战落地,智能体工具集成不再难

MCP协议深度解析:从设计思路到实战落地,智能体工具集成不再难

1. 为什么这一讲值得单独拿出来精讲MCP,全称 Model Context Protocol,是近两年在智能体工程圈子里被反复讨论的一个协议规范。如果你正在做 AI 应用开发,尤其是涉及工具调用、多智能体协作、外部数据源接入这类场景,那 MCP 基本是…

2026/10/19 5:38:26 阅读更多 →
OpenClaw requireApproval 插件:生产环境 AI 代理的人工审批闸门

OpenClaw requireApproval 插件:生产环境 AI 代理的人工审批闸门

OpenClaw 跑得越顺,我心里反而越没底。这句话听起来有点反直觉,但凡是把 OpenClaw 从个人实验搬到团队生产环境的人,多半能对上这个感觉:代理的执行力越强,越没人敢给它在生产环境里完全放开手脚。OpenClaw v2026.3.28…

2026/10/19 5:38:26 阅读更多 →
Agent上下文管理选型:流水式与汉堡式架构对比及混合方案实践

Agent上下文管理选型:流水式与汉堡式架构对比及混合方案实践

1. 从一次上下文溢出事故说起去年冬天,我接手了一个内部知识库问答助手的调优工作。上线第一周就出了状况:用户连续追问七八轮之后,Agent 开始答非所问,甚至把三轮之前已经确认过的订单编号又当成新信息重新询问。日志里最扎眼的一…

2026/10/19 5:38:26 阅读更多 →
PSO-BiLSTM与SHAP可解释性分析:多步时序回归的完整实践

PSO-BiLSTM与SHAP可解释性分析:多步时序回归的完整实践

上个月我手头有一个多步超前回归需求:一段工业设备运行监测数据,十几个连续采集的变量,要用过去24个时刻的观测预报未来三个时刻的一项关键质量指标。业务方提出三个硬性要求——预报要准,模型结果要能解释“到底哪些变量在起作用…

2026/10/19 5:38:26 阅读更多 →
OpenClaw基础版扩展指南:理解skills机制与必备技能清单

OpenClaw基础版扩展指南:理解skills机制与必备技能清单

装完OpenClaw基础版的第一天,很多人都会对着终端界面发愣——程序确实起来了,也能对话了,但让它干点正事,比如整理个文件、抓个网页信息、定时提醒你开会,它却总是回一句"我没有这个能力"。这不奇怪。OpenCl…

2026/10/19 5:38:26 阅读更多 →
AI开发工程师面试全解析:从简历到系统设计的高频考点与备战方法

AI开发工程师面试全解析:从简历到系统设计的高频考点与备战方法

面试这件事,最微妙的地方在于:你以为你在展示自己,面试官却往往在60分钟内只做一件事——验证“如果把这个项目交点给我,我能放心吗”。作为一个面过别人、也被别人面过的AI开发工程师,我见过太多准备充分却答偏的候选…

2026/10/19 5:37:25 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →