Linux之make/Makefile联系


前言

Linux的学习之路是异常地艰难。有关Linux的知识点多而复杂,学习要有耐心并且要花费相对长的时间,下定决心去搞定一个知识点。在介绍make/Makefile的联系前,我想先告诉你们的是,make是一个命令,Makefile是一个文件。另外注意,Makefile的m可大写,可小写,本文为做更好地区分,Makefile中的m一贯保持大写。


正文开始

一、make/Makefile的演示

如果是朋友想直接使用make命令,那么可以仿照下面的代码块。

第一步,写想要编译的源文件。本文将用c语言来编写。

#include<stdio.h>
int main()
{
        printf("hello world");
        printf("hello world");
        printf("hello world");
        return 0;
}

第二步,创建与test.c文件对应的Makefile文件,并且进行相应的编译。

在这里插入图片描述

mytest:test.c
        gcc -o mytest test.c
.PHONY:clean
clean:
        rm -f mytest

第三步 使用make指令编译第一步所编写的源文件

在这里插入图片描述

第四步 清理所编译生成的可执行文件

在这里插入图片描述

二、与Makefile文件内容有关的原理

1.Makefile文件存在的意义

Makefile文件存在的意义是为了构建项目的。(要做一件事情)
通俗地讲,Makefile文件是为了更简便地执行程序。以以上的程序作为一个例子,当编写与test.c对应的Makefile文件后,在编译是只需要写make命令,而不是一长串地输入gcc -o mytest test.c指令,操作更加简便。

2.依赖关系

目标文件与源文件的关系

比如,以上程序中
在这里插入图片描述
就是要把test.c编译成一个可执行文件,并且起名为mytest。
mytest:test.c就是表明一个依赖关系,mytest是在test.c基础上进行某种依赖方法而得到的文件。

另外可以拿生活中的社会关系举例,比如父子关系
小张:老张
小张是老张的儿子,小张可以视为是依赖于老张的

3.依赖方法

目标文件在源文件的基础进行的操作
gcc -o mytest test.c 这条指令就可以称得上是mytest和test.c的依赖关系

上个例子,小张怎样依赖于老张的,他们的依赖关系是什么?
小张是个大学生,他依赖于老张给的生活费而生存。所以据此要编写这个Makefile文件。

小张:老张
			老张给小张生活费

4.依赖性

编写Makefile文件如下

test.out:test.o
        gcc -o test.out test.o
test.o:test.s
        gcc -c -o test.o test.s 
test.s:test.i
        gcc -S -o test.s test.i 
test.i:test.c
        gcc -E -o test.i test.c 

执行make指令
在这里插入图片描述
输入make命令,操作系统会自动在当前目录下寻找名称为makefile或者Makefile的文件,并且默认第一个目标文件为最终的目标文件。该文件以实现第一个目标文件的依赖关系为主,如果该目标文件所依赖的文件并不存在,那么操作系统会在Makefile文件向下寻找,通过完成其他的依赖关系找到此文件,如果并没有依赖关系生成此文件或者是该文件并不存在就会报错。
比如,以上程序中test.out依赖的文件test.o并不存在,操作系统就会在文件中向下去寻找有无可生成test.o的依赖关系,发现第二个依赖关系可以生成,但是test.o依赖的test.s并不存在,则在去循环前几步。该make的命令则通过实现 gcc -E -o test.i test.c生成test.i,再通过实现 gcc -S -o test.s test.i生成test.s,再通过实现 gcc -c -o test.o test.s 生成test.o,最后通过实现gcc -o test.out test.o生成test.out。
make命令的依赖性就像是剥洋葱,一层一层地实现依赖关系,编译获得最终的目标文件。

5.项目清理

在项目中往往存在生成某个可执行文件,在某个时机需要删除该可执行文件,便会用到clean命令。
在使用时要输入make clean才能完成clean命令。

三.对Makefile的初步理解

1.stat命令的补充

stat命令显示文件或目录的详细属性信息包括文件系统状态,比ls命令输出的信息更详细。
在这里插入图片描述

其中,三个表示时间的名称分别表示的含义:

1.Modify(修改时间):文件内容被修改的时间
2.Change(改动时间):文件属性(不只rwx的执行,还有文件内容大小)被修改的时间
往往在修改文件内容时Modify和Change都会修改
3.Access(访问时间):访问文件的时间
特别地,只有读取够一定次数才修改Access的时间

为什么只有读取一定次数才能修改Accsess的时间,而不是访问一次就修改呢?

因为文件操作时是访问的次数多。每次修改文件的属性就会进行一次IO操作。如果每次访问文件就修改文件属性,过多的IO操作会给系统增加负担,影响效率。

2.make为什么只能有效使用一次

在这里插入图片描述
在使用make命令时,发现make命令只有效生成一次。make命令防止源文件被多次重复编译,节省了项目编译的时间,提高效率。
可make命令是怎么防止源文件被多次重复编译的呢?
在查阅相关资料后,不难发现make命令是依据源文件Modify的时间是否早于目标文件Modify时间来更新来编译的。前提是编译过的文件存在,如果源文件Modify的时间晚于Modify的便可以编译。如果未编译过该文件则可以编译。通俗地讲,就是在有效编译一次后,如果源文件被修改,才可以被再次编译。

源文件未被编译过可以进行编译
在这里插入图片描述

源文件被编译过
在这里插入图片描述
a.修改源文件内容,可以编译
在这里插入图片描述

b.修改源文件Access属性,可以编译
其中,touch命令:touch file:如果 file 已存在,则更新 file 的所有时间
在这里插入图片描述

3.对.PHONY修饰的伪目标的理解(为什么make clean可以总是执行)

在上文对make命令为什么只能有效使用一次的详细解释后,就可以很轻松地理解该部分内容

关键字.PHONY修饰的是目标是伪目标,可以总是被执行。
什么是伪目标?为什么能总是被执行?

  • 伪目标是这样一个目标:它不代表一个真正的文件名,在执行make时可以指定这个目标来执行其所在规则定义的命令,有时我们也可以将一个伪目标称为标签
  • 因为伪目标执行的原理于源文件、目标文件访问时间的先后无关,所以可以总是被执行。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值