Linux项目自动化构建工具make和makefile

news2024/10/6 18:22:21

前言

前面我们对yum、vim、gcc/g++做了介绍,本期我们再来介绍一个好用的工具,就是make和makefile!

本期内容介绍

什么是make和makefile

makefile文件内容的解释

make执行makefile的原理

我们想要的makefile

一、什么是make 和 makefile ?

make是一条指令,makefile是一个文件!两个搭配使用完成项目的自动化构建。

make 会根据makefile的内容去完成编译和资源清理工作!

OK,先来举个例子看一下:

此时makefile已经被创建出来并被我进写了一下东西!

这个先暂时不解释,先看看他的效果,下面会逐一解释!

我们上面介绍说,make是一条指令是配合makefile 的内容进行对文件的编译和资源清理的!如何使用?

make 对文件的编译

make clean 对资源的清理

为什么要有make和makefile呢?

此时你会想,我们以前编译的时候没什么make和makefile也不是好好的吗?是的没错!以前编译的时候只有一个或三个文件!但如果在公司源文件可能不止几个,少则几十个多则几百个上千个,如果你都去gcc是不是等你编译完就可以下班了!效率极低,此时如果合理的用make和makefile文件的话,一个make 指令就可以完成 ,这就很大的提高编程的效率!

二、makefile文件内容的解释

这是我们当前的makefile 的内容!它都是什么意思呢?我们来详细介绍一下!

第一行: my.exe是目标文件(你要生成的),冒号(:)右边是这个目标文件所依赖的文件列表(可以有多个,多个用空格隔开)!目标文件 : 依赖文件 称为依赖关系

第二行: 必须是Tab开头(四个空格不行),然后目标文件的依赖方法(就是让依赖的文件做什么事)!

第三行: .PHNOY:xxx 意思是xxx对象的方法总要执行!

第四行: clean也是目标文件,它的依赖文件列表为空(依赖文件可以为空

第五行: 是目标文件的依赖方法

如何理解依赖关系和依赖方法?

只有依赖关系没有依赖方法!

假设你今天月底了没有钱了,拿出了给他个人打了电话!假设你打通你只说了一句爹,我是你儿子,然后挂了!此时你就目标文件,你爹就是你的依赖文件!此时没有依赖方法也就是没指定让依赖方法做什么!你爹此时也很懵逼,这小子是要干啥?此时你告诉你爹我是你儿子是表明了依赖关系,但没说要干啥。所以只有依赖关系没有依赖方法啥也不做!

有依赖关系也有依赖方法!

你爹假设很忙,第一次你挂了也没有当回事!此时你饿了,要吃饭!你就又给你爹打过去了!爹我是你儿子,我没钱了!此时既表明了依赖关系有表明了依赖方法!你爹此时会给你打款过来!

资源清理

工程是要被清理的!像clean这种不是第一个目标表文件的不会自动执行,如果要执行就要make clean执行

如果你要把clean作为第一个目标文件也是可以的!

三、make执行makefile的原理

有了上面的解释,我们就能清楚,在我们执行make时,make实际上去makefile文件中找对应的目标文件,然后会让依赖的方法对依赖文件编译生成目标文件!在执行make clean是就执行删除目标文件!大概是这样,下面我们来在详细的解释一下它的执行原理!

make会在当前的目录下去寻找一个名字是"makefile"或"Makefile"的文件!如果没有找到makefile或Makefile文件会报错,入如果找到了就会在makefile或Makefile文件中找第一个目标文件,并将这个目标文件作为最终的目标文件。如果目标文件的依赖文件不存在就会去找目标文件依赖文件的依赖文件找到找到(参考下面的例子),如果没找到或出现错误,直接退出,什么也不做!!

make只关心文件的依赖性,即如果我找到了依赖关系后冒号后的文件在还是不在我就不管喽~!

还是前面的test.c我们现在再写一个Makefile文件:

make执行时会找makefike此时存在,所以就会在makefile中找第一个目标文件,这里就是mytest,并把mytest当作最终的目标文件!此时mytest目标文件依赖的是test.o的文件,是不存在的,就会去先找test.o第二个目标文件就是,但发现他有依赖test.s就去找test.s发现他依赖test.i,test.i依赖于test.c此时发现有,就先执行当前的依赖方法,这样就一层的照下来,然后返回上去!就和栈或递归一样!

总结:make会根据makefile的依赖关系进行自动的推到,帮助我们执行所有的依赖关系的依赖方法!

即使上面的依赖关系不是这样一步一步的而是乱序的也会一样的,会自动推到,但注意的是乱序时最终生成的目标文件必须是第一个!!!!

为什么makefile对最新的可执行程序,默认不想重新形成?

我们在执行make时发现:如果不修改test.c的内容是无法进行二次连续的make的:

如果可执行程序是最新的不给你形成其实很好理解!假设你的可执行 程序的源文件很大,2000个源文件编译一下就得2小时,假设你就想看一下源码但是不修改,结果你误操作了make了一下,那这样是不是很费时间呀!很不划算!所以他检查如果你的可执行程序是最新的就不给你生成了!!

如何做到的?

这里不生成新的可执行程序很好理解但是他是如何做到的呢???这里就得介绍一下一条指令了:

stat filename  //查看文件的最近修改时间

OK,先解释一下这三个是啥?

Access :文件最近一次被访问的时间,查看文件内容、修改文件内容、都属于访问文件!

Modify:最近一次修改文件内容的时间

Change:最近一次修改文件属性的时间

这三个时间是关联的例如你修改文件的内容,三个都会变!

所以此时就有一个事实:一定是先有源文件再有可执行程序的!

所以makefile会比较可执行程序和源文件的最近修改的时间的前后来判断是否要重新生成的!!!

所以在清理时,加上.PHNOY是为了告诉makefile,当前的目标文件你千万不要这样比较~!!因为资源要清理多次~!

四、我们想要的makefile

makefile有他自己的一套类似于小语言的语法。所以这里要想配置成我们想要的makefile文件前我们需要介绍几个它的符号!

$@  表示取目标文件

$^    表示取所有的依赖文件

所以我们可以把上面makefile文件改成:

但是我们看到他每次都要给我提示gcc xxxxx的!我不想他给我提示了!我们可以在依赖方法的指令前加@

这样写还有一个缺点就是如果要修改makefile文件就会很麻烦尤其是源文件多了,他其实可以支持类似于宏的那种定义!

这就可以支持我们目前基本的开发了!

OK,好兄弟本期分享就到这里,我们下期再见!

结束语:如果结果并非所愿,那就在尘埃落定前奋力一搏!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1549162.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DVB-S系统仿真学习

DVB-S系统用于卫星电视信号传输,发送端框图如下所示 扰码 实际数字通信中,载荷数据的码元会出现长连0或长连1的情况,不利于接收端提取时钟信号,同时会使得数据流中含有大量的低频分量,使得QPSK调制器的相位长时间不变…

Python算法100例-4.6 歌星大奖赛

完整源代码项目地址,关注博主私信源代码后可获取 1.问题描述2.问题分析3.算法设计4.确定程序框架5.完整的程序6.问题拓展7.知识点补充 1.问题描述 在歌星大奖赛中,有10个评委为参赛的选手打分,分数为1~100分。选手最…

金融投贷通(金融投资+贷款通)项目准备

金融投贷通(金融投资贷款通)项目准备 专业术语投资专业术语本息专业术语还款专业术语项目介绍三个子系统技术架构核心流程发布借款标投资业务 项目实施测试流程测试步骤 专业术语 投资专业术语 案例:张三借给李四5W,约定期满1年后…

MySQL 高级语句(二)

一、子查询 1.1 相同表子查询 1.2 不同表/多表子查询 1.3 子查询的应用 1.3.1 语法 1.3.2 insert 子查询 1.3.3 update 子查询 1.3.4 delete 子查询 1.4 exists 关键字 1.4.1 true 1.4.2 false 1.5 as别名 二、视图 2.1 视图和表的区别和联系 2.1.1 区别 2.1.2 …

【面试必备】针对一个案例,怎么测试

思考角度 测试用例设计万能公式功能测试(最重要)界面测试易用性测试性能测试安全性测试兼容性测试容错性测试 常见案例物品类水杯笔 软件类微信发送朋友圈功能 测试用例设计万能公式 在面试中经常会遇到的一类题是,给你一个具体的产品&#…

《Attention Is All You Need》

参考: Attention Is All You Need 论文解读:Attention is All you need Transformer模型中的attention结构作用是什么? 如何最简单、通俗地理解Transformer? Transformer 新型神经网络,基于注意力机制 的 编码器-解码器 的序列处…

数据分析web可视化神器---streamlit框架,无需懂前端也能搭建出精美的web网站页面

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 所属的专栏:数据分析系统化教学,零基础到进阶实战 景天的主页:景天科技苑 文章目录 Streamlit什么是streamli…

国内ip地址推荐,畅享网络新体验!

在数字化时代,IP地址不仅是网络连接的基石,也是互联网产业发展的重要标志。国内作为全球互联网市场的重要参与者,拥有众多IP地址资源。虎观代理小二旨在探索并推荐一些国内IP地址,分析它们的价值所在,并探讨如何更好地…

抖音电商“达人客服”产品上线啦!超多作者邀你一起“321上客服”!

有问题别自己克服,来抖音电商找“达人客服” 当代年轻人购物,正在从机智省变成理智购。越来越多的人在达人直播间购物,看重的不止是优惠力度,还有服务保障。 为了帮助达人更好地服务用户,抖音电商上线了「达人客服」…

BERT模型中句子Tokenize和ID转换的过程

当我们使用BERT或其他类似的预训练语言模型时,将句子转换为token的过程通常涉及以下几个步骤: 初始化Tokenizer:首先,我们需要导入相应的Tokenizer类,并根据需求选择合适的预训练模型进行初始化。 分词(To…

IRIS / Chronicles 数据库结构

对于我们用得最多的关系型数据库来说,首先有的是数据库名字,然后是表名字,然后就是字段名,随后就是一条一条的数据。 对于 IRIS 来说,因为是使用的层级数据库,所以上面的定义就不能完全的照搬了&#xff0…

腾讯云4核8G12M带宽配置服务器能支撑多少人访问?并发数测试

腾讯云4核8G服务器价格:轻量4核8G12M优惠价格646元15个月、CVM S5服务器4核8G配置1437元买1年送3个月。腾讯云4核8G服务器支持多少人同时在线?支持30个并发数,可容纳日均1万IP人数访问。腾讯云百科txybk.com整理4核8G服务器支持多少人同时在线…

MySQL的安装(Linux版)

1.所需要的文件 MySQL.zip 2. 卸载自带的Mysql-libs # 查看是否存在 rpm -qa | grep mariadb# 如果存在则执行命令进行卸载 rpm -e --nodeps mariadb-libs3.在/opt目录下创建MySQL目录并上传所需要的安装包 cd /optmkdir MySQL4.按照编号顺序安装(压缩包在解压完…

【业界动态】数字孪生到底意味着什么

什么是数字孪生?它可以理解为一种技术,也可以理解为某种生态。数字孪生即指将物理实体映射至虚拟空间,进而协助完成预测、决策等动作。随着互联网的建设与发展,数字孪生在未来又会如何落地? 一、数字孪生到底是什么&am…

【Java程序设计】【C00389】基于(JavaWeb)Springboot的校园疫情防控系统(有论文)

基于(JavaWeb)Springboot的校园疫情防控系统(有论文) 项目简介项目获取开发环境项目技术运行截图 博主介绍:java高级开发,从事互联网行业六年,已经做了六年的毕业设计程序开发,开发过…

弹性伸缩 AS

🍁博主简介: 🏅云计算领域优质创作者 🏅2022年CSDN新星计划python赛道第一名 🏅2022年CSDN原力计划优质作者 🏅阿里云ACE认证高级工程师 🏅阿里云开发者社区专…

JAVA 使用POI实现单元格行合并

POI实现单元格行合并 实现效果引入jar代码实现controller层Service层ServiceImpl层实现类 实现效果 如果最后面的三行数据大于1时 那么前面十二行就需要行合并 引入jar <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</arti…

java多线程基本操作方法

目录 一、isAlive&#xff08;&#xff09; 二、 join&#xff08;&#xff09; 三、start和run 四、 volatile() 五、synchronized 1、synchronized 引入 2、死锁 第一种情况&#xff1a;反复加锁 第二种情况 对不同对象嵌套加锁的死锁 3、形成死锁条件 六、wait…

【正点原子FreeRTOS学习笔记】————(10)FreeRTOS时间管理

这里写目录标题 一、延时函数介绍&#xff08;了解&#xff09;二、延时函数解析&#xff08;熟悉&#xff09;三、延时函数演示实验&#xff08;掌握&#xff09; 一、延时函数介绍&#xff08;了解&#xff09; 相对延时&#xff1a;指每次延时都是从执行函数vTaskDelay()开始…

前缀和算法(1)

一维前缀和[模板] 一、题目描述 OJ题目链接&#xff1a;【模板】前缀和_牛客题霸_牛客网 二、思路解析 三、代码 #include <iostream> using namespace std; const int N 100010; long long arr[N], dp[N]; int n, q; int main() {cin >> n >> q;// 读取…