Linux中的`make`与`Makefile`:项目自动化构建工具
Linux中的make与Makefile:项目自动化构建工具
在Linux及类Unix系统中,make是一种广泛使用的自动化构建工具,它通过读取和执行Makefile(或makefile,文件名不区分大小写)中的指令来自动化编译和构建程序。Makefile定义了构建过程中需要执行的命令、依赖关系以及构建目标,极大地简化了复杂项目的构建过程。本文将深入探讨make命令、Makefile的编写规则、常用函数以及高级特性,帮助读者更好地理解和使用这一强大的工具。
一、make命令简介
make命令是一个根据Makefile中的指令来自动编译和链接程序的工具。它首先会检查所有需要编译的源文件以及它们所依赖的库或文件是否是最新的,如果不是,则根据Makefile中的规则重新编译这些文件。这种方式避免了不必要的编译,提高了构建效率。
二、Makefile的基本结构
Makefile由一系列规则(rules)组成,每个规则定义了如何生成一个或多个目标文件(target)。规则的基本格式如下:
target: dependenciescommand...
- target:规则的目标,通常是文件名,也可以是一个伪目标(如
clean)。 - dependencies:目标的依赖文件列表,用于判断目标是否需要重新构建。如果依赖文件比目标文件新,或者目标文件不存在,则执行命令。
- command:当目标需要被构建时执行的命令。每个命令前必须有一个制表符(Tab),而不是空格。
三、Makefile的编写规则
1. 变量
Makefile中可以使用变量来存储文件名、编译选项等,以便在多处重复使用。变量定义和引用的方式如下:
CC=gcc
CFLAGS=-Wall -ghello: hello.o$(CC) $(CFLAGS) -o hello hello.ohello.o: hello.c$(CC) $(CFLAGS) -c hello.c
2. 自动变量
make还定义了一系列自动变量,用于在规则中代表文件名、依赖列表等。常用的自动变量包括$@(代表目标文件名)、$<(代表第一个依赖文件名)、$^(代表所有依赖文件名)等。
3. 伪目标
伪目标不是文件名,而是一个标签,用于执行一些特定的操作,如清理构建文件。伪目标后面通常使用.PHONY来声明,以避免与同名文件冲突。
.PHONY: cleanclean:rm -f *.o hello
4. 模式规则
模式规则允许为符合特定模式的文件定义构建规则,而不需要为每个文件单独编写规则。模式规则使用%作为通配符。
%.o: %.c$(CC) $(CFLAGS) -c $< -o $@
四、Makefile的常用函数
Makefile支持多种内置函数,用于字符串处理、文件名操作、条件判断等。
wildcard:用于查找符合特定模式的文件名列表。patsubst:用于模式替换,将符合模式的字符串替换为另一个字符串。if、ifeq、ifneq、ifdef、ifndef:用于条件判断。
五、高级特性
1. 递归make
在大型项目中,可能会将项目拆分成多个子项目,每个子项目都有自己的Makefile。此时,可以在顶层Makefile中调用子项目的Makefile,实现递归构建。
subdir:cd subdir && $(MAKE)
2. 静态模式规则
静态模式规则是模式规则的一种扩展,它允许更精确地指定目标和依赖的模式。
objects = foo.o bar.oall: $(objects)$(objects): %.o: %.c$(CC) -c $(CFLAGS) $< -o $@
3. 变量覆盖
在命令行中可以通过-e选项或直接在命令行中指定变量值来覆盖Makefile中的变量值。
make CC=clang
4. 隐式规则
make内置了许多隐式规则,用于编译和链接C、C++等语言的源文件。当Makefile中没有为特定目标定义规则时,make会尝试使用隐式规则来构建目标。
六、实践案例
假设我们有一个简单的C语言项目,包含main.c、utils.c和utils.h三个文件,我们希望使用make和Makefile来自动化编译和构建这个项目。下面是一个可能的Makefile示例:
# 定义编译器和编译选项
CC=gcc
CFLAGS=-Wall -g# 定义项目中的源文件和目标文件
SRCS=main.c utils.c
OBJS=$(SRCS:.c=.o)
TARGET=myapp# 默认目标,即当不指定目标时执行的操作
all: $(TARGET)# 链接目标文件生成可执行文件
$(TARGET): $(OBJS)$(CC) $(CFLAGS) -o $@ $^# 编译C源文件生成目标文件
%.o: %.c$(CC) $(CFLAGS) -c $< -o $@# 伪目标,用于清理构建过程中生成的文件
.PHONY: cleanclean:rm -f $(OBJS) $(TARGET)# 依赖关系(如果项目中有头文件,则不需要显式写出,但保持其最新状态很重要)
# 注意:这里不直接写出头文件依赖,因为make会基于时间戳自动检查
# 但对于复杂的项目,可能需要使用-MM等gcc选项生成依赖关系# 如果需要自动处理头文件依赖,可以在Makefile中加入如下规则(示例)
# 注意:这里只是一个简单的示例,实际项目中可能需要更复杂的逻辑
%.d: %.c@set -e; rm -f $@; \$(CC) -MM $(CFLAGS) $< > $@.$$$$; \sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \rm -f $@.$$$$# 引入所有.d文件(如果存在),这些文件包含了文件的依赖关系
-include $(SRCS:.c=.d)
然而,上面的%.d规则及其sed命令是处理头文件依赖的一种较为复杂的方式,主要用于生成.d文件,这些文件包含了源文件和目标文件以及它们所依赖的头文件的列表。在上面的示例中,如果源文件更改或依赖的头文件更改,则.d文件也会更新,并且make会基于这些更新来重新编译相应的源文件。
但是,对于简单的项目或刚开始使用make的用户来说,可能不希望一开始就引入这么复杂的逻辑。在实际应用中,可以根据项目的复杂度和需求来选择是否自动生成依赖关系。
对于上面的简单项目,如果头文件(如utils.h)更改,用户通常需要手动触发重新编译。但在更复杂的项目中,使用自动生成依赖关系的方法可以极大地简化构建过程,并减少因忘记更新依赖关系而导致的编译错误。
七、总结
make和Makefile是Linux及类Unix系统中不可或缺的项目自动化构建工具。通过编写Makefile,开发者可以定义项目的构建规则、依赖关系以及编译选项,从而实现高效的自动化构建。本文介绍了make命令的基本用法、Makefile的编写规则、常用函数以及高级特性,并给出了一个简单项目的Makefile示例。希望这些内容能够帮助读者更好地理解和使用make和Makefile,提高项目构建的效率和质量。
相关文章:
Linux中的`make`与`Makefile`:项目自动化构建工具
Linux中的make与Makefile:项目自动化构建工具 在Linux及类Unix系统中,make是一种广泛使用的自动化构建工具,它通过读取和执行Makefile(或makefile,文件名不区分大小写)中的指令来自动化编译和构建程序。Ma…...
GitHub开源项目精选:轻量级预约/预订日历组件,用React和TypeScript构建
在日常开发中,我们经常需要在项目中添加预约或预订功能。今天给大家推荐一个超级轻量级的预约/预订日历组件,它是用React和TypeScript构建的,非常适合那些需要简单易用的日历解决方案的开发者。 安装方法: 你可以选择使用npm或者y…...
闲钱放在哪里?收益稳定且又高!
家庭理财,最大的问题就是,手里这点闲钱,说多不多,但打理起来,还真的很”挠头“。 放银行,存款利率接二连三下调,利息又又又要变少了! 投资出去,看着到处的雷声隆隆&…...
【Linux】简易线程池项目
线程池是一个可以巩固一些线程相关接口 && 加强理解的一个小项目。 注意:这里的线程池使用的线程并不是Linux原生接口,而是经过封装的,具体请看线程封装,为什么不使用原生接口? 因为原生接口一旦进行pthread…...
基于vue框架的NBA球星管理系统1878g(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
系统程序文件列表 项目功能:用户,球员,球员数据,榜单类型,联盟榜单,重要比赛回放,精彩时刻视频,视频专栏,本赛季赛程,十佳球,投票信息,投票结果 开题报告内容 基于Vue框架的NBA球星管理系统 开题报告 一、选题背景 随着互联网的普及和体育产业的蓬勃发展&#x…...
【docker】Dockerfile练习
1、overlay文件系统原理测试 cd /mnt mkdir A B C worker merged echo "From A">./A/a.txt echo "From A">./A/b.txt echo "From A">./A/c.txt echo "From B">./B/a.txt echo "From B">./B/d.txt echo &quo…...
数据可视化的魔法:Python Matplotlib库的奇妙之旅
标题:数据可视化的魔法:Python Matplotlib库的奇妙之旅 在数据科学和分析领域,数据可视化是一种将复杂数据转换为图形表示的强有力工具,它可以帮助我们更直观地理解数据。Python中的Matplotlib库是进行数据可视化的瑞士军刀&…...
Python数据科学的秘密武器:Pandas库的深度解析
标题:Python数据科学的秘密武器:Pandas库的深度解析 Python作为数据科学领域的宠儿,其强大的数据处理能力离不开Pandas库的加持。Pandas是一个开源的数据分析和操作库,它提供了快速、灵活和表达力强的数据结构,旨在使…...
云计算实训24——python基本环境搭建、变量和数据类型、数据集合、py脚本
一、python环境搭建 确保拥有阿里云镜像 查看python环境 [rootpython ~]# yum list installed | grep python 查看epel是否安装 [rootpython ~]# yum list installed | grep epel 安装epel [rootpython ~]# yum -y install epel-release.noarch 查看是否安装python3 [rootpyt…...
深入了解网络性能监控(NPM):优化网络性能的关键
目录 网络性能监控(NPM)是什么? 关键网络性能指标 案例分享:如何利用NPM优化网络性能 实用技巧:如何高效运维你的网络 结论 随着企业依赖于互联网和内部网络进行业务运营,网络的稳定性和性能显得尤为重…...
Vue引入使用iconfont字体图标
由于element-ui或element-plus提供的图标有时候并不能满足日常需求,所以这篇介绍一下前端引入阿里巴巴矢量图标库使用,不止是vue使用,不限于vue2、vue3,html或是其他框架也是同样的道理,只要引入都是同样可以使用的。 1. 首先进入阿里巴巴矢量图标库官网 官网:https://…...
Doc2Vec
Doc2Vec 是一种扩展自 Word2Vec 的算法,它不仅可以生成词向量,还可以生成句子或文档的向量。下面是一个使用 Doc2Vec 比较两个句子的具体过程: 步骤 1: 训练 Doc2Vec 模型 首先,你需要有一个训练好的 Doc2Vec 模型。训练过程大致…...
MES生产过程透明管理,实施掌握生产每个环节
MES(制造执行系统)生产过程透明管理,旨在通过集成多种技术手段和管理模块,实现对生产过程的实时监控和精准掌握,确保每个生产环节都能被清晰地记录和追踪。以下是对MES生产过程透明管理的详细阐述: 一、MES…...
Java解析压缩包,并根据指定文件夹上传文件
方法 public Multimap<String, String> getCodeBucketMultimap(HttpServletRequest request)throws IOException {MultipartHttpServletRequest multiRequest (MultipartHttpServletRequest) request;// 基于servlet获取文件流List<MultipartFile> multipartFile…...
【HTML】纯前台字符验证码
效果图: 大致思路: 1.在<canvas>画布里写出几个字符; 2.给字符一个随机的角度和颜色; 3.给字符上画出一些干扰线和干扰点。 <canvas width"100" height"30" id"canvasRef" click"…...
如何在 Vue.js 项目中动态设置页面标题
目录 方法 1:使用 Vue Router 的元信息(meta) 步骤 1: 配置路由元信息 步骤 2: 使用路由守卫设置标题 方法 2:在组件内设置标题 在组件挂载时设置标题 使用响应式数据动态更新标题 在开发 Vue.js 应用时,设置动态页面标题是常见需求,尤其当应用包含多个页面时,为每…...
Eval绕过限制参数限制
PHP Eval函数参数限制在16个字符 PHP代码 <?php$param $_REQUEST[param]; if (strlen($param) < 17 && stripos($param, eval) false && stripos($param, assert) false){eval($param);}?># 部署环境属于ubuntu系统 通过GET传参绕过 由于是…...
计算机网络408考研 2021
2021 计算机网络408考研2021年真题解析_哔哩哔哩_bilibili 1 1 11 1 1 11...
element table表格树形数据展示
element table表格树形数据展示 1、效果 2、代码 <el-table ref"pointMultipleTable" border class"table-box" :data"[damActiveObj]"row-key"id" :tree-props"{ children: children }" :expand-row-keys"expand…...
Ubuntu 安装 Snipaste
一、下载 Snipaste 下载Snipastehttps://zh.snipaste.com/ 二、在/opt 创建 Snipaste 目录,创建 bin 和 icon 子目录,将 Snipaste.AppImage 移动到 bin 目录 三、创建快捷键图标 1. 创建桌面图标,右键→允许运行 yammiemy-pc >/home/y…...
Kerberos身份认证原理与实战排错指南
1. 为什么今天还要花时间搞懂 Kerberos?——一个被低估的“老协议”正在悄悄支撑着你的日常你每天登录公司内网查邮件、访问财务系统提交报销、用 Jenkins 构建代码、甚至在 Windows 域环境中打开一台同事的共享文件夹……这些看似顺滑的操作背后,大概率…...
MCP Server生产级配置:Playwright与LLM集成的避坑指南
1. 这不是又一个“Playwright入门教程”,而是一份能直接塞进CI流水线的MCP Server生产级配置实录你有没有遇到过这样的场景:团队刚决定用AI驱动自动化测试,技术选型会上大家一致看好Playwright MCP(Model Context Protocol&#…...
BurpSuite 2025插件开发JDK版本兼容性实战指南
1. 为什么BurpSuite插件开发环境总在JDK版本上翻车?你是不是也经历过:下载好BurpSuite最新版2025.4,兴冲冲打开插件开发文档,照着官方示例写完第一个HelloWorld插件,一编译——java.lang.UnsupportedClassVersionError…...
森优时铁锌维发根养黑用三个月真实效果实测:内服营养养黑的客观测评
"森优时铁锌维发根养黑用三个月真实效果实测显示,针对压力、熬夜引发的早白问题,通过内服补充毛囊所需营养的方式,多数使用者能感受到发根韧性提升、新生发色素沉淀改善,整体改善效果因人而异,合规的营养补充是目…...
学习日志(三)【php语法学习,iscc校赛wp】
1. 任务 1.1.1.1.1.1. 知识部分 rce看【之前的笔记?】php的知识点学习继续jwt token好像是比赛的题目考察内容,我看看php伪协议 1.1.1.1.1.2. 题目 参加iscc比赛【五一】rce题目 1.1.1.1.1.3. 环境配置 把vscode搞好,上学期没有把Php配…...
MeloTTS实战指南:解决多语言TTS部署中的核心挑战
MeloTTS实战指南:解决多语言TTS部署中的核心挑战 【免费下载链接】MeloTTS High-quality multi-lingual text-to-speech library by MyShell.ai. Support English, Spanish, French, Chinese, Japanese and Korean. 项目地址: https://gitcode.com/GitHub_Trendin…...
用PyTorch复现FactorVAE:一个能同时预测收益和风险的量化模型实战教程
用PyTorch实战FactorVAE:构建收益与风险双预测的量化模型 在量化投资领域,传统线性因子模型正逐渐被非线性机器学习方法所取代。然而金融数据特有的低信噪比特性,使得直接从市场数据中提取有效因子成为一项艰巨挑战。本文将深入探讨如何利用P…...
如何利用开源工具Unlock-Music解决音乐平台加密格式兼容问题
如何利用开源工具Unlock-Music解决音乐平台加密格式兼容问题 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库: 1. https://github.com/unlock-music/unlock-music ;2. https://git.unlock-music.dev/um/web 项目地址: https://gi…...
Nacos CVE-2021-29441漏洞深度解析:User-Agent绕过与鉴权失效
1. 这个漏洞不是“改个Header就能登录”,而是Nacos鉴权体系的一道裂缝CVE-2021-29441这个编号在Nacos社区里曾被轻描淡写地归为“低危”,直到我接手一个金融客户线上告警——他们的Nacos集群在凌晨三点被批量创建了37个高权限用户,所有操作日…...
【C++】零基础入门 · 第 4 节:循环结构(while、for、do-while)
上一节我们学习了条件判断,这一节来学习循环结构。循环让程序能够重复执行某段代码,直到满足特定条件为止。C 提供了三种循环语句:while、for 和 do-while。 1. while 循环:先判断后执行 while 循环在每次执行前先检查条件&#x…...
