栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux下Makefile,make本质解析(看这一篇就够了)

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux下Makefile,make本质解析(看这一篇就够了)

目录
      • make
      • Makefile
      • .PHONY

前言:
适合于有点make和Makefile基础的,这样更好理解并做出思考。
下面提出的观点,建议自己进行实践证明。

make

首先明确这是一个命令行命名,它的作用为,在当前路径下,找到名为Makefile的文件,解释Makefile中的指令。
插入一句,为什么是在当前路径下找Makefile,是因为Shell的运行原理,除去部分的内建命令,大多数命令执行原理是为,Shell创建子进程,找到命令文件,执行进程替换,执行相关代码。(非内建命令==可执行程序)
为此,我们可以查看进程的默认路径。

上诉为进程的资源,cwd即表示此进程的默认路径(创建文件,找文件等)。

Makefile

Makefile本质就是文件。只不过配合make使用,此文件的内容需要做出特殊格式处理,比如基础的常见的Makefile文件:

对于第二行,通常说mytest依赖于test.c ,依赖关系为第3行,即gcc test.c -o mytest。
当我看到clean这个目标文件的定义和执行时,大胆假设,小心求证后,我总结出了Makefile中的命名格式与make配合中的本质。

为什么要如此写,直接提出观点并进行证明。
上诉Makefile是常规的写法即用法,来看下面的Makefile不常规写法(Makefile常使用于项目中多文件的管理)

make,会执行pwd命令,这时可以发现make,和Makefile本质上就是一种接口关系,:前定义接口名称,叫做目标文件。
make在当前目录下找Makefile并在Makefile文件里执行相应接口,如无特殊指定,即make后没接相应目标文件(接口名称),默认生成第一个目标文件(或者可以说进入第一个接口)。
目标文件时通俗的说法,接下来我将用接口来说明,因为接口更加符合make和Makefile的本质。
依赖方法可以是命令行中执行的任何命令,如上诉的pwd,touch创建一个文件,不过需注意,依赖方法是存在于接口的下方,并且前面必须接(Tab)。
那么我们就可以知道,Makefile基本使用规则,

make选择对应的接口,选择后进入接口内,执行命令行指令,如未显示调用哪个接口,make将从上到下,在Makefile中执行遇到的第一个接口。

简单阐述完接口,我们来看看,当有依赖文件时,Makefile和make又该如何执行,或者有如何不同。来看以下代码

当目标文件或者说接口 all 有着依赖文件 a.txt 时,当在命名行敲入make并执行时,shell创建子进程执行make,而make进程有着当前路径的属性,当出现目标文件后方带有依赖文件时(:后的文件常称为依赖文件),make将在当前路径下查找此路径下有无依赖文件,如有无a.txt,如果有,则进入接口,执行命令,如无,将会在Makefile中查找有无相应的与 依赖文件同名的目标文件(接口),如果有此目标文件,则先执行与依赖文件同名的接口内的命名,执行完后,将回到所需依赖文件的接口内,执行此接口内的命令。
让我们来看个列子就能明白上面有点绕的文字表达。

上诉代码中,如果make此路径下,有着a.txt,那么执行make指令时,默认从第一个接口即这的all接口进入,因为当前路径存在着a.txt,满足依赖,此时才进行all接口的方法(命令)。如果当前路径下无a.txt,make将在Makefile中找,有无与依赖文件,即这的a.txt同名的目标文件(接口),如果有,则进入a.txt接口,由于此接口无依赖文件,所以可直接进入,执行对应的依赖方法(命令)。
所以总结如下

  • 依赖文件对于目标文件(或者说接口)来说,就像一把钥匙,有此钥匙,你才可以进入接口,执行接口内的内容。
  • 此关系类比就像,存在着多个门,每一个接口对应一个门,而依赖文件存在的那一刻,这道门就被上锁了,为此需要相应的依赖文件这把钥匙(即获取相应的资格),来打开这道门。
  • make对于上锁的门(接口),会有相应的找钥匙策略,首先在当前路径下找,有无此接口所需的钥匙,如果没有,则在Makefile里面找,看有无与所需钥匙(即依赖文件)同名的门(接口),有并且此门无需钥匙,则进入执行,然后回到最开始所需钥匙的接口,进入执行,在找的过程中,以此类推上诉操作。

对于最后一点,我需要做出相应的解释,即为什么make会在Makefile中找与依赖文件同名的接口,以此来进入最开始的接口?如果用钥匙来比喻依赖文件的话,这样的策略也并没有实体的钥匙啊,为什么可以获取进入的资格?
首先我们得明确,make和Makefile的使用场景,它们并不会像我上面这样使用,它们默认被用来处理大型的工程项目,实现 “自动化编译” ,完成自动化构建。
如像最开始我们所常见的用法

是实现生成目标文件的,所以为什么被称为目标文件,如mytest这个接口,进入后执行命令,生成对应的与接口同名的目标文件,而make和Makefile默认是处理项目工程中代码的,所以它们默认认为,只要执行接口,会生成默认的目标文件,即有了钥匙的实体,所以它们支持,尽管此接口需要钥匙,但我有着与钥匙同名的目标文件,默认会生成实体钥匙(不管你是否真的生成),因此有资格进入最开始的接口。不过能进入接口不代表能执行里面的内容(命令),如果执行内容本身需要文件的存在,如果没有,那么无疑会报错。

make时,会出现以下现象(执行pwd)并报错。

重点声明,上面多数代码都不会是实际Makefile中的相关用法和格式,我只是以此来阐述make和Makefile的本质理解

.PHONY

此语法定义伪目标,让目标总是能被执行。
伪目标,个人理解是给程序员看的,毕竟Makefile中的目标文件默认认为会生成相应的目标文件,而用.PHONY来声明一下,就表示,此目标不会生成对应的目标文件。
总是能被执行怎么理解,编译是有成本的,如果代码没有做出修改,gcc编译器是不会编译的,这时用.PHONY声明一下,就可以总是被执行编译了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/838201.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号