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…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
基于stm32F10x 系列微控制器的智能电子琴(附完整项目源码、详细接线及讲解视频)
注:文章末尾网盘链接中自取成品使用演示视频、项目源码、项目文档 所用硬件:STM32F103C8T6、无源蜂鸣器、44矩阵键盘、flash存储模块、OLED显示屏、RGB三色灯、面包板、杜邦线、usb转ttl串口 stm32f103c8t6 面包板 …...
react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架
1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...
WinUI3开发_使用mica效果
简介 Mica(云母)是Windows10/11上的一种现代化效果,是Windows10/11上所使用的Fluent Design(设计语言)里的一个效果,Windows10/11上所使用的Fluent Design皆旨在于打造一个人类、通用和真正感觉与 Windows 一样的设计。 WinUI3就是Windows10/11上的一个…...
