快速上手makefile自动化构建工具

makefile自动化构建工具


文章目录

makefile自动化构建工具

    makefile背景

    简单认识makefile

    依赖关系与依赖方法

      生成项目

      清理项目

    ACM时间

    语法补充

      .PHONY修饰

      特殊符号替换

    Makefile的推导过程

    总结


前言:

  在windows下,很多东西都是编译器直接帮你做好的,而在Linux下并不是这样,如果也想要实现自动化,就要会写makefile,那么话不多说,开启我们今天的话题!

在这里插入图片描述


✈️ makefile背景

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

✈️ 简单认识makefile

  我们不妨先编写一个makefile文件,简单来认识一下,首先准备一个C的源文件,再在当前目录下创建 makefile/Makefile(两者皆可) 文件:

在这里插入图片描述

  打开makefile文件,写下如下内容:

mybin:file.c
	gcc -o mybin file.c

在这里插入图片描述

  使用 make 命令进行自动化编译,再运行形成的可执行程序:

在这里插入图片描述
  以上就是一个简单的自动化编译的过程,其实就是把指令放到文件里去执行。但是,我接下来要解释一下makefile文件里的内容。


✈️ 依赖关系与依赖方法

🔎生成项目

  makefile里面,最重要的一个概念就是,依赖关系和依赖方法

在这里插入图片描述

  • mybin这里是目标文件
  • file.c这里是依赖关系列表,可以有多个文件

为了方便大家理解,我这里举两个例子:

  例1月初的时候,阿熊拿了生活费,风光无限,但是现在到月底了,阿熊没钱了,这个时候阿熊要给他父亲打电话,当父亲电话接通的那刻,阿熊说了一句:“爸,我是阿熊。” 然后立马挂断,只留下一脸懵的父亲…

  阿熊月底没钱了,给父亲打电话,说明了自己身份,这个就是依赖关系,但是光有依赖关系并不能解决问题,所以还需要具体的依赖方法。

  例2这时,阿熊再次拿起电话打给父亲:“爸,我刚才点错了,这个月我生活费没了,打点钱过来。” 虽然阿熊父亲很生气,钱花这么快,但是还是把钱打了过去。

  阿熊打电话,并且拿到了钱,拿到钱的这个过程就是所谓的 依赖方法,依赖方法也就是具体的执行过程,在第二行中,一个 Tab键 后所写的gcc的指令就是依赖方法。


🔎清理项目

  在vs中,我们既有生成资源,也有清理资源,那么在Linux下能否清理资源呢?答案是可以的。

  同样在makefile文件下,接着写下如下内容:

clean:
	rm -f mybin

在这里插入图片描述
  clean所 依赖的文件为空,也就是clean 不依赖任何文件,而clean的依赖方法就是删除形成的可执行程序。

在这里插入图片描述

  现在我们既可以进行自动化编译,也可以进行自动化清理,例如:

在这里插入图片描述

  为什么我们自动化编译只需要make,而资源清理却需要make clean?我们不妨在makefile文件中将两者位置互换:

在这里插入图片描述

  这时我们再进行make,我们会发现:

在这里插入图片描述
结论
  make指令默认是makefile文件中的第一个依赖关系! 其实这时因为,makefile在形成目标文件的时候,默认是从上到下扫描makefile文件的,默认形成的是第一个目标文件。


✈️ ACM时间

  我们来看这样一个现象:

在这里插入图片描述
  通过上面的现象,我们发现,我们只能make一次,生成对应的可执行程序之后make会检测生成的可执行程序是否存在,存在就不再生成。
  而当我们对源文件进行修改时,重新再次make又能够生成新的可执行程序,那么make是到底如何识别我更新了程序呢?

  其实这是因为每个文件都存在着三种时间,而make命令则是根据某个时间来判断你的文件是否更改过,是否更新过,再继续做出判断到底执不执行make。


为了解决上述问题,我们有必要了解一下Linux下时间的概念。

  使用指令 stat 进行查看源文件的时间:

在这里插入图片描述
stat 命令可以用来显示文件的详细信息,包括文件的状态、权限、所有者以及时间信息,其中这三个时间概念:

  • Access(访问时间):代表文件最后被访问的时间。当文件被访问时,这个时间会被更新。
  • Change(变更时间):当文件的属性被改变时,那么Change这个时间就会被更新。
  • Modify(修改时间):代表文件内容的最后修改时间。当文件的内容被修改时,这个时间就会被更新。

在刚开始学Linux的时候我们都知道:

文件 = 内容 + 属性

  当我们修改一个源文件时,不仅源文件的Modify时间更新,并且Change时间也会被更新:

在这里插入图片描述

  因为当我们对源代码进行修改时,我们可能新增了、删除、修改了代码,这些操作很有 可能让我们文件的大小发生变化,所以 Change的时间也会跟着改变

  而Acess时间是指文件访问时间,比如使用cat命令对文件内容访问,但是当我们连续多次访问时:

在这里插入图片描述

  当我们第一次访问时,AccessTime会改变,但是当我们连续多次访问test.c文件后,AccessTime反而不变了?

这是因为,原本Linux的AccessTime每次访问都会改变,但是,用的多了大家发现,AccessTime的使用次数远远比ModifyTime和ChangeTime大得多。而每次更改文件属性也会消耗资源,所以现在Linux规定ATime的刷新是有一段时差的。


  经过以上分析,我们make判断文件更新的时间似乎是Modify时间,没错,就是Mtime,也就是说,如果我们能改变ModifyTime那么再重新make的时候就可以成功执行了。

  说到更改Modify时间,我们可以想到 touch命令如果touch的文件不存在,则创建新的文件,如果存在,则更新Mtime

在这里插入图片描述

  可以看到使用touch命令更改Mtime就可以重新make了


✈️ 语法补充

🔎.PHONY修饰

  我们在windows的os下,vs中,编译文件之后不需要你手动清理资源,而是vs自动清理资源,那么在Linux下有没有对应的方式来进行自动化清理呢?

  其实也是有的,这里就需要补充一点新的语法

.PHONY:目标文件#修饰目标文件,使之成为伪目标,总是被执行

在这里插入图片描述

  可以看到,加上 .PHONY 修饰之后,我们make就可以多次使用了,其实修饰伪目标就是 忽略文件的Mtime是否更新,所以就可以一直使用make。

  而我们一般遵循着伪目标修饰清理工作,编译工作还是交给编译器的选择,以时间的更新来判断执不执行make,但是 清理工作是一定要执行 的,所以我们 通常把.PHONY修饰需要清理的目标文件

在这里插入图片描述


🔎特殊符号替换

  其实在makefile文件里,我们不需要出现目标文件和源文件,因为make/makefile会帮助我们识别目标文件和源文件,可以使用特殊符号代替:

  • $@表示目标文件
  • $^表示依赖文件列表

  所以我们makefile的文件就可以这样写:

在这里插入图片描述
  测试是否可行:

在这里插入图片描述

  其实在makefile文件中我们甚至可以不用写gcc 和 -o选项,我们可以定义makefile变量:

g=gcc#变量g就表示gcc
flag=-o#变量flag就表示-o
  • 替换格式: $(变量)

  这样我们就能对 gcc 和选项 -o 进行替换了:

在这里插入图片描述

  我们进行测试:

在这里插入图片描述

  同样我们在写依赖关系的时候也可以用变量进行替换:

在这里插入图片描述


✈️ Makefile的推导过程

  其实makefile的目标文件所依赖的文件是.o文件,可是我们没有.o文件。而**.o文件依赖于.s文件**,我们也没有.s文件。.s文件依赖于.i文件,我们也没有.i文件。.i文件依赖于.c文件,我们有.c文件!
  所以我们的依赖关系就是:

在这里插入图片描述

  而到了.c文件,我们就可以写出依赖方法了:

在这里插入图片描述
  有了这个依赖方法,我们就能得到.i文件了,所以我们.i的依赖方法也能写出来,同理,.s,.o的依赖方法也能依次写出:

在这里插入图片描述
  其实这就是makefile文件的 语法推导 过程,首先 根据依赖关系向下推导,再根据依赖方法从下往上推导 ,很类似于入栈出栈的过程。

  测试是否是自底向上执行依赖方法:

在这里插入图片描述


✈️ 总结:

  •  makefile有一个重要概念——依赖关系和依赖方法,依赖关系又有目标文件和依赖关系列表。
  •  简单写一个makefile的文件包含资源清理,并且成功执行。
  •  ACM时间,make/makefile是根据Mtime来做判断的。
  •  一些补充语法,以及makefile的语法推导过程。

在这里插入图片描述
  如果这篇文章对你有帮助的话,还望能三连支持一下博主~~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

im6ull学习总结(二)Framebuffer 应用编程

1 LCD操作原理 linux中通过framebuffer驱动程序来控制LCD。framebuffer中包含LCD的参数,大小为LCD分辨率xbpp。framebuffer 是一块内存 内存中保存了一帧图像。 关于图像的帧指的是在图像处理中,一帧(Frame)是指图像序列中的单个…

一篇文章带你轻松入门Python

Python基础 1. Hello World! Python命令行 假设你已经安装好了Python, 那么在命令提示符输入: python 将直接进入python。然后在命令行提示符>>>后面输入: >>>print(Hello World!) 可以看到,随后在屏幕上输出: print是一个常用函数&#xf…

python学习14

前言:相信看到这篇文章的小伙伴都或多或少有一些编程基础,懂得一些linux的基本命令了吧,本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python:一种编程语言&…

Analytify Pro Google Analytics Goals Addon谷歌分析目标插件

Analytify Pro Google Analytics Goals Addon谷歌分析目标插件是一款极其巧妙且具有开创性的工具,它赋予用户细致跟踪和全面分析其网站性能的卓越能力。有了这个非凡的插件,个人可以毫不费力地建立并认真监控他们的Google Analytics目标,从而…

du和df

du 和df 不一致的问题: 情况如下: innode 没有满 同事求助, 他在删掉一个很大的文件后, 磁盘空间依旧没释放。上去一看, 果然 df 看到磁盘空间占用依旧是100%,等等 du 看了一把,磁盘空间剩余很…

低延时视频技术的应用场景和挑战

编者按 无线网络对人们的生活产生了巨大的影响,而5G技术的引入将彻底改变我们与世界互联互通的方式。在5G时代,实现万物互联离不开低延时技术的应用。 LiveVideoStackCon 2023 深圳站邀请到秒点科技的CEO扶凯,为大家分享低延时技术在物联网、…

Impala大数据框架学习网站,大数据技能提升必备利器!

介绍:Impala是Cloudera开发的新型查询系统,它能够对存储在HDFS、HBaseImpala是Cloudera开发的新型查询系统,它能够对存储在HDFS、HBase以及S3上的数据进行快速的交互式SQL查询。此外,Impala与Hive使用了统一的存储系统、同样的元数…

什么是https证书?

HTTPS证书,也称为SSL(Secure Sockets Layer)证书或TLS(Transport Layer Security)证书,是一种数字证书,用于在网络上建立安全的加密连接。它的主要目的是确保在互联网上进行的数据传输的安全性和…

提升设计效率:全面了解如何使用Figma插件

Figma组件库包括颜色、字体、图标、按钮、阴影、圆角、间距等。当Figma组件库的样式和Figma组件达到一定数量时,将难以维护,设计和开发的对接成本将大大提高。Figma可以在同一母版下单独设置样式,而不影响与母版之前的关系,这是Sk…

w4操作系统之windows上创建隐藏用户

隐藏用户–在windows上创建隐藏用户 1.首先查看现有哪些用户。(通过net user 命令) 2.然后创建隐藏用户(net user client$ 123 /add) 此时出现报错信息。原因是登录用户没权限。需要用管理员的权限 3.用管理员身份运行cmd&am…

AspectJWeaver之Gadget分析

前言&#xff1a; 今天看了下ysoserial的AspectJWeaver方法&#xff0c;分析了下其是如何通过调用SimpleCache$StorableCachingMap来实现写文件&#xff0c;这里把分析的流程写下来&#xff1a; 首先我们要看下其所需要的jar包&#xff1a; <dependencies><dependen…

drf知识-08

Django之了解DRF框架 # 介绍&#xff1a;DRF全称 django rest framework # 背景&#xff1a; 在序列化与反序列化时&#xff0c;虽然操作的数据不尽相同&#xff0c;但是执行的过程却是相似的&#xff0c;也就是说这部分代码是可以复用简化编写的 增&#xff1a;校验请…

基于SSM实现的电动汽车充电网点管理系统

一、系统架构 前端&#xff1a;jsp | jquery | bootstrap | css 后端&#xff1a;spring | springmvc | jdbc 环境&#xff1a;jdk1.8 | mysql 二、代码及数据库 三、功能介绍 01. web端-首页 02. web端-登录 03. web端-注册 04. web端-我要充电 05. web端-个人中心-消…

网络编程『简易TCP网络程序』

&#x1f52d;个人主页&#xff1a; 北 海 &#x1f6dc;所属专栏&#xff1a; Linux学习之旅、神奇的网络世界 &#x1f4bb;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 文章目录 &#x1f324;️前言&#x1f326;️正文TCP网络程序1.字符串回响1.1.核心功能1.2.程序…

java设计模式学习之【解释器模式】

文章目录 引言解释器模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用表达式解析示例代码地址 引言 在我们的日常生活中&#xff0c;语言的翻译和理解是沟通的关键。每种语言都有自己的语法规则&#xff0c;而翻译人员和计算机程序需要理解并遵循这些规则来…

线程基础知识(三)

前言 之前两篇文章介绍了线程的基本概念和锁的基本知识&#xff0c;本文主要是学习同步机制&#xff0c;包括使用synchronized关键字、ReentrantLock等&#xff0c;了解锁的种类&#xff0c;死锁、竞争条件等并发编程中常见的问题。 关键字synchronized synchronied关键字可…

leaflet学习笔记-初始化vue项目(一)

leaflet简介 Leaflet是一款开源的轻量级交互式地图可视化JavaScript库&#xff0c;能够满足大多数开发者的地图可视化需求&#xff0c;其最早的版本大小仅仅38 KB。Leaflet能够在主流的计算机或移动设备上高效运行&#xff0c;其功能可通过插件进行扩展&#xff0c;拥有易于使用…

Java——值得收藏的Java final修饰符总结!!!

Java final修饰符总结 一、final修饰类二、final修饰方法三、final修饰变量 总结 算下刚转Java到现在也有三个多月了&#xff0c;所以打算对Java的知识进行汇总一下&#xff0c;本篇文章介绍一下Java的final修饰符的作用&#xff0c;final表示最后的、最终的含义&#xff0c;fi…

PyTorch 进阶指南,10个必须知道的原则

PyTorch 是一种流行的深度学习框架&#xff0c;它提供了强大的工具和灵活的接口&#xff0c;使得开发者能够搭建和训练各种神经网络模型。这份指南旨在为开发者提供一些有用的原则&#xff0c;以帮助他们在PyTorch中编写高效、可维护和可扩展的代码。 如果你对 Pytorch 还处于…

如何在Mac中设置三指拖移,这里有详细步骤

三指拖移手势允许你选择文本&#xff0c;或通过在触控板上用三指拖动窗口或任何其他元素来移动它。它可以用于快速移动或调整窗口、文件或图像在屏幕上的位置。 然而&#xff0c;这个手势在默认情况下是禁用的&#xff0c;因此在本教程中&#xff0c;我们将向你展示如何在你的…
最新文章