Linux基础之makefile/make

目录

一、背景

 二、makefile和make的讲解

2.1 使用方法

2.2 伪目标文件

2.3 文件的属性以及属性的更新

2.4 makefile的自动推导


一、背景

这里会提及为什么要使用makefile和make,以及他们是什么和作用。

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

简单来说:

makefile 是一个在当前目录下存在的一个具有特定格式的文本文件

make是一条指令

 二、makefile和make的讲解

2.1 使用方法

       既然makefile和make是这么好的一个工具,那我们该如何去使用他呢。莫急,且听我与你细细道来。首先在上文我们就说了,makefile是一个文件,那我们就得创建一个文件,且其命名必须为makefile(首字母可以大写)。例如我编写的这个:

        文件创建好了,那么其内容我们该怎么去编写呢,先看例子:

       这里先简单的说明一下这段代码是什么意思,随着我之后的讲解你们会逐渐地理解。 
       首先第一行代码,表明mybin和code.c具有依赖关系呢,这个大家慢慢就可以理解,其中 :左边的文件主要依赖于右边的文件,:右边可以有多个文件(先简单这样理解)。
       第二行代码,表面第一行依赖关系的依赖方法,通过这行代码我们也可以看出通过gcc指令将code.c编译生成mybin文件。
       第三行代码,表示clean是一个伪目标,这个下文我们会具体的说明。
       第四行代码,表示clean没有具体的依赖文件。
       第五行代码,同样表示其依赖方法,这里主要是删除mybin这个可执行文件。
接下来,让我们看看效果:
 
       可以发现,我们仅仅通过make指令就形成了我们的可执行文件,同样我们还通过make clean指令删除了我们的mybin文件。
       我相信细心的同学肯定会发现,为什么我们生成mybin文件的时候不需要写成make mybin呢?
这是因为当我们输入make指令时,其会自动在Makefile文件中从上自下的去检索第一个有效指令。如果我们把clean和mybin换一下位置,结果可就不一样了哦,大家可以自行尝试一下。

       我们其实还可以用其他方式来编写我们的makefile,这里我直接给大家上代码,再根据代码进行介绍。

      在编写makefile时,我们可以像前三行一样,去给我们的文件重新起一个名字,使用格式为 
$(+命名名字)。
      在看第一个关联关系,出现一个 $^ 和一个 $@ ,那这两个符号是什么意思呢。

$^ :表示关联关系的右边 即 :的右边

$@:表示关联关系的左边 即 :的左边

2.2 伪目标文件

在刚刚的代码中我们看到了这样一段代码:

首先将结论:

.PHONY 将clean修饰成了一个伪目标

那么这个伪目标有什么作用呢

作用:当被修饰成伪目标后,该指令可以总是被执行(依赖方法总是被执行的,不会被任何方式所拦截)

为什么要说可以总是被执行呢,难道系统还会拦截我们的指令不成,事实上确实时会的。例如:

       可以发现我们的make mybin在执行一次之后就不在让我们去执行了,而make clean 却可以反复的去执行。那这是为什么呢,系统是如何去拦截我们的命令的呢?,请看下文。

2.3 文件的属性以及属性的更新

首先我们来介绍一个指令:

stat + 文件名 ------------------可以查看一个文件的属性

例如我们现在就来看看刚刚通过make指令创建的code.c文件:

我们可以看到在文件中有很多属性,这里我们具体来说是后面三个。

Access : 访问时间。

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

Change:最近一次文件属性被修改的时间
注意:文件 = 内容 + 属性

回归正题,为什么make/makefile总是不让我们重新编译代码?

       其实这是为了去提高我们的编译效率。如果我们的源代码什么都没改,那么我们一直的反复编译时没有任何意义的,所以其总是不让我们重新编译代码。

那么其是怎么做到这一点的呢?

       主要通过一个文件的修改时间,光一个时间有什么用呢。所以时间并不是本质,通过时间对比出文件的新旧才是本质(更新后的文件才有重新编译的价值)。那么其和谁去对比呢?不要忘了,我们生成的可执行程序也是一个文件,要知道重新编译的本质不就是重新写入一个二进制可执行文件吗,那么其的修改时间就一定会更改。
        这里还有一个逻辑,第一次编译的时候,一定是先有的源文件,才有的bin文件,那么
源文件的修改时间一定会小于bin文件的修改时间。那么在之后,我们对源文件做修改的时候一定有,源文件的修改时间大于bin文件的修改时间(此时还没进行编译)。这样不就可以对比出文件的新旧,进而去达到防止我们对一个文件反复编译的效果了吗。

       这里重新介绍一下touch,其还可以更新一个文件的时间。可以用man指令进行查看。(我这只截取了一部分)

可以看到 -a是修改访问时间,-m是修改mtime。

       我们在这里可以通过这个指令来印证上面我们所说的。
这个时候是不让make的:

其时间属性如下:

接着我们touch一下,然后再次观察code.c的时间属性:

可以很明显的发现其发生了变化,我们在试一试可不可以make:

实验成功,刚好印证了我们上面所说。

补充:

       我们所看到的文件,一般在哪里存放着呢?一般是放在磁盘,更改文件时间的本质其实就是访问磁盘。其实系统不是很愿意去访问外设的,因为很慢,会导致效率的降低。但是一般而言,一个文件被查看的频率是非常高的(不是用户访问),如果每次都要去更改Access的话,会导致Linux系统充满大量的访问磁盘的IO操作,变相的减慢系统效率。为了减少这样的访问,系统设置了一个每经过一定次数的查看,再进行一次修改Access的操作。

2.4 makefile的自动推导

这里我们同样先用代码举例:

       这段代码很有意思,当我们要创建mybin时,目录中却没有code.o,怎么办,那么他就会在makefile中从上至下的去找,看有没有关于code.o的依赖关系,很明显根据这段代码他一直会往下找,直到遇到code.c(该文件在目录中存在),这往下找的过程其实可以看做时一个入栈的过程,而当找到code.c,那么接下来就会相当于一个出栈的过程一直生成所要的文件。
        这部分过程可以看做makefile/make的推导能力(当然这只是很小的一部分)。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++:哈希表和unordered系列容器的封装

一、unordered系列关联式容器的介绍 在C98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到log2N,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是&…

【CTF Web】XCTF GFSJ0484 command_execution Writeup(RCE+Linux命令)

command_execution 小宁写了个ping功能,但没有写waf,X老师告诉她这是非常危险的,你知道为什么吗。 解法 输入个ip试一下。原来是直接执行 ping 指令。 好好好,这不就能直接执行指令了么。先找找 flag 在哪里。 ; find / -name flag.txt找到了&#xff…

AI人才争夺战,华尔街入局:豪掷百万美元年薪抢人 | 最新快讯

量子位公众号 QbitAI 继硅谷之后,华尔街也入局“AI 人才争夺大战”。 他们的目标非常明确——抢的就是高精尖的 AI 专家。 △图源:Business Insider 现在这条“街”上,不论是银行、对冲基金还是私募股权公司都已纷纷下场,可谓是豪…

【6D位姿估计】ZebraPose 层次化分组策略 由粗到细的表面编码

前言 本文介绍6D位姿估计的方法ZebraPose,也可以称为六自由度物体姿态估计,输入单张图片,输出物体的三维位置和三维方向。 它来自CVPR2022的论文,通过层次化分组策略,高效地编码物体表面的信息。 ZebraPose提出了一…

产业观察:电机驱动成为人形机器人的动力核心

前不久,波士顿动力发布一则“再见,液压Atlas”视频,宣告其著名的液压驱动双足人形机器人Atlas正式退役。这则视频引起全球所有Atlas粉丝的高度关注。然而紧接着,波士顿动力便又推出了全部由电机驱动的新一代Atlas机器人&#xff0…

微信一键登录怎么做的?流程是什么?

实现方法:三种方法 点击【登录】按钮 》(系统框)绑定手机号》如果绑定:登录成功点击【登录】按钮》直接登录成功了 >后续可以在设置中【绑定手机号】点击【登录】按钮 -》 打开一个新的页面(绑定手机号):自己的表单 -》进行手机号绑定的验证 方式一:业务流程)用…

vtk教程:禁止VTK弹出警告窗口warning

在使用VTK(Visualization Toolkit)进行可视化操作时,有时候会弹出警告窗口(warning messages),这些警告可能是由于数据问题或是API使用不当等原因触发的。 如果你希望在使用VTK时禁用这些警告窗口&#xff…

谷歌明年6月关闭 Google Fit 运动记录API,要求开发者迁移至Android Health平台 | 最新快讯

5 月 6 日消息,谷歌近日发布官方新闻稿,宣布将在明年 6 月使用 Android Health 平台取代 Google Fit 运动记录 API,开发人员应当尽早启动迁移计划。 谷歌自 2022 年起逐渐扩大对 Android Health 平台的投资,旨在减少平台碎片化&am…

Docker入门指南:Docker容器的部署(一)

🍀 前言 博客地址: CSDN:https://blog.csdn.net/powerbiubiu 👋 简介 当今软件开发领域中,Docker 成为了一种流行的容器化技术。Docker 可以帮助开发者将应用程序及其依赖项打包到一个独立且可移植的容器中&#xf…

代码随想录打卡第14天第18天

二叉树 1 二叉树部分的一些新知 (1)二叉树的定义,C方法一定要知道,相对于链表而言,二叉树就是多了两个指针,即左右子节点 struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : …

直线度测量仪出现测量偏差时如何矫正?

直线度测量仪是精密测量仪器,应用于圆形线材、棒材、管材类产品的直线度尺寸检测,既可检测每米直线度尺寸,又可检测整体直线度尺寸。无论是在线检测还是离线检测均可实现。 数据计算:系统根据测头1和测头3采集的X轴方向位置值拟合…

【前端】创建跳动字符效果的前端技术实现

创建跳动字符效果的前端技术实现 在前端开发中,动态视效能够显著增强用户体验。本文介绍一种实现字符跳动效果的技术方案,通过简单的HTML、CSS和JavaScript代码,你可以为网页文本添加生动的交互动画。这种效果可以用于吸引用户注意、增强品牌…