第2天.make的学习(第二部分)对伪目标的理解

一、目标,依赖,命令
也许大家觉得这个不重要,但今天我有了新的认识,所以写了下来。这三个就是Makefile的全部,但今天我要重点说一下它的执行顺序。每个Makefile都有且只有一个终极目标,下设若干子目标,make的规则会检查目标与依赖的时间戳,依赖中的某一个比目标新,说明目标已经过时,需要更新。这里要着重说一下,make会将目标的依赖及依赖的依赖全部展开,然后才能决定是否需要更新终极目标。
a.out
/     |    \
/       |     \
_  /       _       \_
/             |            \
hello.o       world.o      main.o
_/                   |                  \_
/                      |                     \
hello.c             world.c                main.c
对于这个例子,相信大家都能写出Makefile。make在解析Makefile时,就会生成上面的依赖树,它会自底向上比较时间戳,若下层的新,则执行上层目标所对应的命令,然后,依次执行上上层的命令(因为,底层更新了,所以上面的都需要更新)。如果底层不比上层的新,则不执行上层目标所对应的命令(这就是make的聪明之处)。例如:我们更改了hello.c文件,make在解析Makefile时,首先比较的不是a.out与hello.o谁更新(如果make真的这么做,那么make就会直接退出,因为自你上次执行make时,a.out会比hello.o更新,而我们修改hello.c,并不会影响hello.o的时间戳), 而是依赖树的最底端,hello.c与hello.o的时间戳,因为hello.c的修改,目标hello.o的命令会被执行,进而触发a.out所对应的命令。目标werld.o与main.o所对应的命令当然不会被执行。make的输出看上去是这个样子的
gcc -c hello.c
gcc hello.o world.o main.o     
在make 的info文档中有这样一段话:(注意粗体字)
3.9 How `make' Reads a Makefile
===============================
GNU `make' does its work in two distinct phases.  During the first
phase it reads all the makefiles, included makefiles, etc. and
internalizes all the variables and their values, implicit and explicit
rules, and constructs a dependency graph of all the targets and their
prerequisites.  During the second phase, `make' uses these internal
structures to determine what targets will need to be rebuilt and to
invoke the rules necessary to do so.
4 Writing Rules
***************
A "rule" appears in the makefile and says when and how to remake
certain files, called the rule's "targets" (most often only one per
rule).  It lists the other files that are the "prerequisites" of the
target, and "commands" to use to create or update the target.
The order of rules is not significant, except for determining the
"default goal": the target for `make' to consider, if you do not
otherwise specify one.  The default goal is the target of the first
rule in the first makefile.  If the first rule has multiple targets,
only the first target is taken as the default.  There are two
exceptions: a target starting with a period is not a default unless it
contains one or more slashes, `/', as well; and, a target that defines
a pattern rule has no effect on the default goal.  (*Note Defining and
Redefining Pattern Rules: Pattern Rules.)
二、伪目标
伪目标总被认为是过期的,总被认为需要被更新。伪目标又称标签,之所以这样叫,是为了与真实的文件进行区别。那伪目标是如何工作的,我们可以将它当作普通文件,但不管出现在目标中,还是依赖中,都以为着它是将要被更新的普通文件。
1、伪目标做目标,普通文件做依赖
这是最常见的一种,典型的all伪目标  .PHONY:all
all: prog1 prog2       #执行make后,会一次生成两个可执行程序
prog1:  a.c  ...
command
...
prog2:  b.c ...
command
...
分析:在这个Makefile中。.PHONY是第一个目标,但它以点开头,不会作为终极目标(在上面的英文中有解释),所以终极目标是all,make的职责所在就是重建这个all目标。因为all是伪目标,make命令总认为它需要被更新,而更新它,需要首先更新prog1 和 prog2 ,这就达到了一次make而生成两个可执行文件。
2、伪目标做目标,伪目标又做依赖(虽然称为伪目标,但也可做依赖,目标与依赖是相互转化的,就像上面的hello.o,它是hello.c的目标,又是a.out的依赖)
.PHONY: all subdir apps
all: subdir apps
subdir: prog1 prog2
apps:  prog3 prog4
prog1: a.c
command...   
prog2: b.c
command...
prog3: c.c
command...
prog4: d.c
command...
分析:all是终极目标,它依赖于subdir 和 apps ,因这两个都是伪目标,即:他们需要被更新。subdir又依赖于prog1 和 prog2 这就回到了上面的那种情况。这种形式经常出现在大的工程中,是对上面一种情况的扩展,我们可以修改all 或 subdir 或  apps 中的依赖,来决定我们需要那些应用程序,裁剪掉那些应用程序。你应该听说过内核裁剪与移植吧,所谓裁剪,就是修改Makefile的目标,不生成我们不需要的东东;所谓移植,就是修改Makefile的编译参数,换成其他的编译工具。
3、普通文件做目标,伪目标做依赖
all: prog
prog: a.c prt
command...
.PHONY: prt
prt:
@echo "this is prt"
分析:每次执行make时,this is prt都会出现在屏幕上。尽管prog不需要被更新,但prt中的命令依然要被执行。make会这样来解析,prog依赖于prt,而prt有需要被更新(因为它是伪目标),这意味着this si prt会出现在屏幕上,prt更新完成后,prog目标中的command...就会被执行(我们假定a.c没有被更改)。事实上我们那个文件也没有更改,但是prog目标中的命令还是被执行了,info make中不建议这样做
A phony target should not be a prerequisite of a real target file;
if it is, its commands are run every time `make' goes to update that
file.
总结:在伪目标中始终贯穿着这样一句话:伪目标总被认为是需要被更新的。我也是依据这句话来分析上述伪目标的应用。伪目标可以与真实文件重名,典型的clean用法,因为make知道,我们只是想执行clean下的命令,而不是去重建一个叫做clean的文件,这也是我们有时把它解释称标签的原因。关于上述第二种情况,info make中有这样一个解释
When one phony target is a prerequisite of another, it serves as a
subroutine of the other.  For example, here `make cleanall' will delete
the object files, the difference files, and the file `program':
.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
             rm program
cleanobj :
             rm *.o
cleandiff :
             rm *.diff

一、目标,依赖,命令
    这三个是makefile的全部内容,现在来说一下它的执行顺序

转载于:https://www.cnblogs.com/SFTD/p/3622126.html

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

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

相关文章

ASP.NET(c#)常用类函数

常用函数系列: public static string Get_ClientIP() 得到客户端IP public static string Get_CMac(string IP) 得到客户端 CMac 地址 public static string RequestF(string xPName,string xPType,int xLenDef) 安全接收数据系列 public static string Show_Cont(string xStr)…

快别发语音了! | 今日最佳

全世界只有3.14 %的人关注了青少年数学之旅(图源千叶的堕天使绅士猫_呜喵0w0,侵权删)我们无论遇到什么困难,都不要怕,微笑着面对它!消除恐惧的最好方法就是面对恐惧!

软件项目管理概览----版本控制

随着软件项目规模的不断扩大,项目管理的作用变得越来越重要。如果一个需要长期维护的项目不能得到很好的管理与控制,“软件腐败”就会发生,用不了多久,我们的程序可能就会像一团拌好的炸酱面一样难以找到头绪,维护的成…

设计模式之原型

原型模式介绍完整拷贝原型模式主要解决的问题就是创建重复对象,而这部分对象内容本身比较复杂,生成过程可能从库或者RPC接口中获取数据的耗时较长,因此采用克隆的方式节省时间。原型模式是一种创建型设计模式,使你能够复制已有对象…

华为服务器停止响应,windows服务器停止工作

windows服务器停止工作 内容精选换一换无法通过远程桌面连接裸金属服务器时,我们推荐您按照以下思路排查问题。检查是否符合登录条件检查网络是否正常检查防火墙配置是否正常远程访问端口配置异常尝试重启裸金属服务器确认是否已经按照裸金属服务器登录前的准备工作…

专题1.1——Exchange2013部署前准备条件

本专题将主要介绍Exchange2013从部署前准备、正式部署到应用配置和维护的整个过程。博文是我在自己做测试的过程中自己编写的,如果大家有什么意见或问题也欢迎一起讨论交流。废话不多说,下面进入正题。本节将主要介绍部署Exchange2013之前需要准备的先决…

Tabs

Tabs控件的功能是在一个页面上显示多个选项卡。由两部分组成:TabContainer和TabPanel.前者表示整个一组选项卡,而后者表示其中的一个选项卡。 属性列表: OnClientActiveTabChanged:单击选项卡标题触发的事件 Height:选项卡的高度 ContentTemp…

这些让人看瞎了的设计!实力证明,数学才是世界的最终boss!

全世界只有3.14 %的人关注了青少年数学之旅昨天小天刷微博,看到了一组动图,一时间我都不知道是我的眼睛出了错,还是我的大脑反应不过来。奇了怪了!怎么箭头反转了180后,还是原样!问题到底出在哪里&#xff…

你真的了解低代码平台吗?

从 2020 年疫情之后,低代码这个概念就突然变得火热起来,各大自媒体纷纷推出介绍低代码的文章,InfoQ 也曾发表过一篇《为什么我说低代码是“行业毒瘤”?》引发了热议,明道的创始人任向晖随后在自己的公众号写文章《低代…

服务器抽屉式维护,一种服务器用可顺序运动的滑轨

1.一种服务器用可顺序运动的滑轨,包括内轨(1)、中轨(2)和外轨(3),内轨(1)、中轨 (2)和外轨⑶依次连接,其特征在于:还包括外壳⑷,外壳⑷内设有滑行架(5),滑行架 (5)与外轨(3)相连接,中轨(2)上设有…

50个常用sql语句

Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师表 问题: 1、查询“001”课程比“002”课程成绩高的所有学生的学号; select a.S# from (select s#,score from SC where C#001) a,(selec…

无边工作,无际遐想

又是一个胡乱涂鸦,最近很长一段时间我就像临产孕妇样,挣扎在“生产”边缘,每次将手放在键盘上,努力憋出一丝一缕。却就是伸不出个头来。还好,我比孕妇自由,可以停下来休息休息。有句话说的好:生…

图像还可以这样玩!如何用OpenCV处理图像?

全世界只有3.14 % 的人关注了青少年数学之旅人工智能近年来呈现爆发式发展,计算机视觉和深度学习作为人工智能的两大支柱学科,近年来得到迅速发展。今天小天将带着大家走进计算机视觉!所谓计算机视觉,就是指用摄影机和电脑代替人眼…

java集合学习笔记 ---Collections类对集合的处理

2019独角兽企业重金招聘Python工程师标准>>> 包名:java.util.CollectionsCollections是个类,不是接口有以下方法,部分列举1.对List进行升序排序public static void sort(List list)如果要进行降序排序,可以在sort函数中制定降序public static…

如何入门.NET Core ? 推荐这10个优秀的开源项目!

.NET 5马上就要发布了,还不知道这些.NET Core开源项目?只推荐干货!当然这些开源项目都是个人或组织开发的。1.Ant Design Blazor.NET进行客户端Web开发又一利器。微软官方认可,微软Build2020开发者大会Blazor介绍中,提…

.NET设计模式(7):创建型模式专题总结(Creational Pattern)

概述 创建型模式,就是用来创建对象的模式,抽象了实例化的过程。它帮助一个系统独立于如何创建、组合和表示它的那些对象。本文对五种常用创建型模式进行了比较,通过一个游戏开发场景的例子来说该如何使用创建型模式。 为什么需要创建型模式 所…

南方人第一次见到雪的样子。。。| 今日最佳

全世界只有3.14 %的人关注了青少年数学之旅(视频来源沙雕图,侵权删)

逆转是怎么发生的?

郑昀玩聚SR 20090527 曾几何时,香港警员的95%都参与了贪腐。当一个一个警员被迫加入行贿受贿行列中时,当其他公共服务机构也参与进来时,当民众不行贿就难以使用公权资源时,看上去似乎整个体系烂透了,无药可救&#xff…

MVVM架构~knockoutjs系列之包括区域级联列表的增删改

返回目录 这个例子我做了几次,之前总是有BUG,目前测试后,确定没有BUG才发上来的,主要功能是实现“我的银行”模块的增删改的功能,这个里面包括了级联列表的区域选择,这部分是难点,在开发过程中&…

ABP Vnext 4.4:统一Ef Core的DbContext/移除EF Core Migrations项目

Abp vnext 4.4出现了一个比较重大的变更:在Startup template中移除了EF Core Migrations项目,本文翻译自community.abp.io/articl由于本文发布的时候Abp vnext的版本还没有到4.4,所以本文演示了如何从4.4以前的版本移除EntityFrameworkCore.D…