【Linux】07.Linux 下的项目自动化构建工具——make/makefile

news2024/9/20 2:59:13

前言

  • 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
  • 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
  • makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
  • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建

一、认识make和makefile

1.1 编译文件

在这里插入图片描述
在这里插入图片描述
我们可以看到make指令之后就自动生成了code文件

接下来对各个部分进行解释:
在这里插入图片描述

1.2 清理文件

在这里插入图片描述
在这里插入图片描述
我们看到make指令就对code进行了清理

接下来对清理部分进行解释:
在这里插入图片描述

1.3 make的原理

上述的代码本质上应该是这样的:
在这里插入图片描述

  1. make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
  2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“code”这个文件,并把这个文件作为最终的目标文件。
  3. 如果code文件不存在,或是code所依赖的后面的code.o文件的文件修改时间要比code这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成code这个文件。
  4. 如果code所依赖的code.o文件不存在,那么make会在当前文件中找目标为code.o文件的依赖性,如果找到则再根据那一个规则生成code.o文件。(这有点像一个堆栈的过程)
  5. 当然,你的C文件和H文件是存在的啦,于是make会生成code.o 文件,然后再用code.o 文件声明make的终极任务,也就是执行文件code了。
  6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
  7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
  8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。

二、.PHONY 是什么

2.1 认识 .PHONY

.PHNOY 可以理解成 makefile 中声明伪目标的关键字

主要作用是让目标文件的依赖方法总是被执行,下面来证明一下:
在这里插入图片描述
通过是否给code文件添加 .PHONY 我们可以看出没有.PHONY时我们的文件在make时就会显示文件已经是最新编译状态,并没有生成新的文件。

可能这时候就会有人来测试给clean去掉 .PHONY ,然后测试发现不管有没有.PHONY,make clean 指令总是能执行的,这就不得不谈一谈.pHONY的原理了。

2.2 .PHONY的原理

我们现在就想知道.PHONY是怎么实现的,为什么有的时候依赖关系就是可以多次执行,而有些时候依赖关系就不执行了。
其实归结到根本,.PHONY 是通过时间判断的,当源文件的更改时间小于可执行程序的修改时间时就不会执行了,这也恰恰符合了我们的预期:既然文件是最新的那就自然不需要更新了

接下来我们就来验证一下我们上面的话是否是正确的:
使用stat指令即可查看文件的属性信息
我们可以看到三种时间:Access、Modify、Change
他们分别代表着什么意思呢?
在这里插入图片描述
在这里插入图片描述
我们看到此时的源文件修改时间是小于可执行程序的,.PHONY就是通过比较源代码产生的时间与可执行程序产生的时间来决定是否进行编译的。

这时候又会有人问了:那为什么clean在去点.PHONY之后他还是可以被多次执行呢?
这是因为 clean里的依赖方法不被时间所强制限定

三、进一步认识makefile

  1. makefile文件会被make从上到下的的进行扫描,第一个目标名是可以缺省的,如果我们像执行其他的依赖关系、依赖方法,使用 make+目标名称
  2. 对于我们执行的makefile时总是会打印我们的指令的信息,我们可以通过在指令前加入@的方式来只显示执行结果

在这里插入图片描述

  1. makefile会自动推导的,一直推导过程,把方法进栈,直到推导到依赖文件存在,然后逆序实现所有的依赖方法,上面演示过了
  2. 更普适的写法:
    在这里插入图片描述
  3. makefile默认一次只生成一个可执行程序,我们如何才能一次生成多个可执行程序呢?
    在这里插入图片描述
    我们只需要使用伪目标操作即可。

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

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

相关文章

序列化组件对比

1、msgpack介绍 1.MsgPack产生的数据更小,从而在数据传输过程中网络压力更小 2.MsgPack兼容性差,必须按照顺序保存字段 3.MsgPack是二进制序列化格式,兼容跨语言 官网地址: https://msgpack.org/ 官方介绍:Its lik…

Android13系统源码内置App并通过AIDL调用获取内置存储卡的真实大小

jix 进行从事Android系统源码开发不得不在原有的系统上内置自己的App。通过内置App一般都需要调用些系统才能访问的系统级App。App的部署和调试需要依赖源码系统。通过命令 : mm 来实现。 第三方App想调用内置的app需要通过跨进程调用。 这里通过AIDL来实现跨进程…

RK3568平台(平台总线篇)SPI驱动框架分析

一.SPI 子系统框架 可以将上面这一 SPI 子系统划分为三个层次,分别为用户空间、内核空间和硬件层,内核空间就包括 SPI 设备驱动层、SPI 核心层和 SPI 适配器驱动层,而本章的主要内容就是介绍 SPI 子系统框架中的内核空间。 SPI 适配器驱动层: SPI 适配器驱动层是 SPI 子系…

【STM32】SPI

SPI又是另一个超级常见的外设通信方式。 大部分图片来源:正点原子HAL库课程 专栏目录:记录自己的嵌入式学习之路-CSDN博客 目录 1 基本概念 1.1 与IIC的区别 1.2 引脚 1.3 移位原理 1.4 四种工作模式 2 NOR Flash 2.1 25Q12…

论文《Graph Structural Attack by Perturbing Spectral Distance》笔记

【SPAC 2022 KDD】大多数现有攻击方法在空间域中操作图,而对傅里叶域中图卷积的脆弱性研究较少。作者提出了一种名为SPectral AttaCk(SPAC)的攻击方法,通过最大化谱距离来实施攻击,并提出了一种有效的近似方法来降低特…

R语言股价跳跃点识别:隐马尔可夫hmm和 GARCH-Jump对sp500金融时间序列分析

全文链接:https://tecdat.cn/?p37479 分析师:Yue Ji 在突发事件发生后,股价会相应的发生较大幅度的上涨或下跌,称为跳跃现象,跳跃现象会给金融投资带来极大风险,因而对跳跃点的识别对于风控而言是很重要的…

web渗透:SQL注入漏洞WAF绕过

目录 如何检测和防范SQL注入攻击中的编码伪装? 检测SQL注入攻击中的编码伪装 防范SQL注入攻击中的编码伪装 WAF在处理SQL注入时为什么有时会对大小写不敏感? SQL注入中的联合查询注入有哪些常见的攻击方式? 在绕过Web应用防火墙&#xf…

实时计算Flink:推动行业变革的新时代引擎(附金融/汽车/物流/零售案例)

实时计算Flink:推动行业变革的新时代引擎(附金融/汽车/物流/零售案例) 前言实时计算Flink 前言 在当今数字化高速发展的时代,数据的价值愈发凸显,而实时计算技术则成为了挖掘数据价值的关键利器。阿里云实时计算 Flin…

道格拉斯-普克 Douglas-Peuker(DP算法) python php实现

废话不多说,直接开干! 最近在做一个车联网项目,有一个场景是车辆定时上报当前所在经纬度等位置信息上报给平台,平台通过web页面在高德地图上展示车辆行驶路径。 说明 道格拉斯-普克算法 (Douglas–Peucker algorithm,亦…

Leetcode面试经典150题-17.电话号码的字母组合

突然发现回溯题最近考的好多,其实没啥技术含量 解法都在代码里,不懂就留言或者私信 class Solution {public static final char[][] digitsCharArr {{},{},{a,b,c},/**数字2可以代表的字符 */{d,e,f},{g,h,i},{j,k,l},{m,n,o},{p,q,r,s},{t,u,v},{w,x…

【数据结构入门】二叉树之堆排序及链式二叉树

目录 前言 一、堆排序 1.概念 2.堆排序思想 3.具体步骤 4.实现 5.复杂度 二、堆的应用——TopK问题 三、链式二叉树 1.二叉树创建 2.二叉树遍历 1)前序、中序以及后序遍历 2)层序遍历 3.结点个数以及高度 1)结点个数&#xff1a…

阿里巴巴中间件canal的搭建和使用以及linux命令下使用mail发送html格式的邮件

一、阿里巴巴中间件canal的搭建和使用 canal可以用来监控数据库数据的变化(binlog日志),从而获得指定数据的变化。canal是应阿里巴巴存在杭州和美国的双机房部署,存在跨机房同步的业务需求时开始逐步的尝试基于数据库的日志解析,获取增量变更…

Netty三

Netty TCP拆包粘包 二次编码方式 常用二次解码器 网络应用程序基本步骤 数据结构设计 完善客户端 客户端实例 Netty编程易错点

C++ 设计模式——适配者模式

C 设计模式——适配者模式 C 设计模式——适配者模式1. 主要组成成分2. 逐步构建适配者模式2.1 目标抽象类定义2.2 源类实现2.3 适配器类实现2.4 客户端 3. 适配者模式 UML 图适配者模式 UML 图解析 5. 类适配者6. 适配者模式的优点7. 适配者模式的缺点8. 适配者模式适用场景总…

永久去除windows11推荐产品的软件

永久去除windows11推荐产品的软件 去除windows11 推荐的项目,并用来固定软件 要求 22621及以上版本 企业版,专业教育版,教育版(可以自行找工具切换,无需重装系统,非常方便的。) [软件原创作者]&#xff…

【Python】Python 函数综合指南——从基础到高阶

文章目录 Python 函数综合指南1. 函数介绍1.1 什么是函数?1.2 定义函数示例:1.3 调用函数1.4 函数参数1.4.1 必需参数1.4.2 默认参数1.4.3 关键字参数1.4.4 可变长度参数 2. Python 内置函数2.1 字符串处理函数示例: 2.2 数学函数示例&#x…

音视频相关

ffmpeg 安装 1. 源码安装 git clone https://git.ffmpeg.org/ffmpeg.git 2. 配置 编译 安装 ./configure --prefix/usr/local/ffmpeg --enable-debug3 --enable-shared --disable-static --disable-x86asm --enable-ffplaymake -jnproc && make install Q: 没有ff…

C++ 基础学习

提示并输入一个字符串&#xff0c;统计该字符串中字母个数、数字个数、空格个数、其他字符的个数 #include <iostream>using namespace std;int main() {cout<<"请输入字符串:";string str;getline(cin,str);int num0;int alp0;int spa0;int other0;int …

大语言模型-GPT3-Language Models are Few-Shot Learners

一、背景信息&#xff1a; GPT3是于2020 年由OpenAI 发布的预训练语言模型。 GPT3在自然语言处理&#xff08;NLP&#xff09;任务中表现出色&#xff0c;可以生成连贯的文本、回答问题、进行对话等。 GPT3的网络架构继续沿用GPT1、GPT2的是多层Transformer Decoder改的结构。…

论文笔记:GEO-BLEU: Similarity Measure for Geospatial Sequences

22 sigspatial 1 intro 提出了一种空间轨迹相似性度量的方法比较了两种传统相似度度量的不足 DTW 基本特征是它完全对齐序列以进行测量&#xff0c;而不考虑它们之间共享的局部特征这适用于完全对齐的序列&#xff0c;但不适用于逐步对齐没有太多意义的序列BLEU 适用于不完全…