Makefile编译原理 make的隐性规则

news2025/1/19 2:41:45

一.makefile 中的同名目标

下面程序怎么执行?为什么?

实验1 :makefile 中出现同名目标时

.PHONY : all 

all : 
	@echo "command-1"

all : 
	@echo "command-2"

VAR := test

all :
	@echo "all : $(VAR)"




mhr@ubuntu:~/work/makefile1$ make all
makefile:12: warning: overriding recipe for target 'all'
makefile:8: warning: ignoring old recipe for target 'all'
all : test
mhr@ubuntu:~/work/makefile1$ 
mhr@ubuntu:~/work/makefile1$ 

以最新定义的命令为准,之前定义的全部忽略。
过程:当make解释器解析这个makefile到 @echo “command-2” 的时候 ,就会将 @echo “command-2” 覆盖掉之前解析出来的 @echo “command-1” 命令。接着向下解析,当解析到 @echo “all : $(VAR)” 的时候,又将 @echo “command-2” 覆盖掉。并不是一下子就知道用哪个命令 而是从上而下的解析出来的。

 注意:当使用include关键字包含其他文件时,需要确保被包含文件中的同名目标只有依赖,没有命令,否则,同名目标的命令将被覆盖。

实验2:不同makefile中相同目标的命令覆盖

makefile

.PHONY : all 

VAR := test

all : 
	@echo "all : $(VAR)"

include 1.mk

1.mk

all : 
	@echo "this is command from 1.mk"



mhr@ubuntu:~/work/makefile1$ make all
1.mk:3: warning: overriding recipe for target 'all'
makefile:8: warning: ignoring old recipe for target 'all'
this is command from 1.mk
mhr@ubuntu:~/work/makefile1$ 

二.make中的隐性规则

make 不仅仅是一个单独的脚本解释器,随着make而发布的还有一些默认实现好的规则,我们可以将这些规则的结合看成是make 的库,这是很正常的现象,当今软件 大部分解释器都自带标准库,标准库中存在一些预定义的变量,预定义的函数,以及预定义的规则,而这些预定的规则就是我们所说的隐式规则。当make 解释器发现makefile 中有目标没有提供任何的规则,此时make解释器就会去尝试去自己的标准库中查找有没有提供规则可以拿来用。如果找到了就用隐式规则,如果找不到的话才会最终报错。

下面makefile能编译成功吗?为什么?

#获取所有.c源文件名字存放在 列表中
SRCS := $(wildcard *.c)

#替换后缀 得到目标文件的列表
OBJS := $(SRCS:.c=.o)


app.out : $(OBJS)
	#链接成可执行程序
	$(CC) -o $@ $^
	$(RM) $^
	@echo "Target ==> $@"

按照预想 这个程序是不会执行的,因为这个makefile 中 根本没提供任何关于 目标文件的规则啊 怎么得到目标文件呢?我们猜测 make 之后会报错。

但是实验结果是这样的:

mhr@ubuntu:~/work/makefile1$ 
mhr@ubuntu:~/work/makefile1$ make
cc    -c -o main.o main.c 
cc    -c -o func.o func.c
cc -o app.out main.o func.o
rm -f main.o func.o
Target ==> app.out
mhr@ubuntu:~/work/makefile1$ 

神奇啊? 我们的makefile中没有任何关于目标文件的规则,可是make怎么会编译得到 .o目标文件的呢??

实验的过程表明 make 是通过如下命令得到的.o文件:

cc    -c -o main.o main.c 
cc    -c -o func.o func.c

两个问题:
问题1 : 是谁指挥make 编译得到目标文件
问题2:上面的编译过程中的 cc变量哪里来的?? rm 变量哪里来的 ???

答:make 解释器在解释执行这一段代码的时候就发现,与.o目标文件相关的规则在当前的makefilez中是没有定义的,此时 make 就会到自带的标准库中寻找有没有相关的隐式规则,结果真的找到了相关的隐式规则,该规则就是 .o文件可以通过.c文件得到,通过 cc 命令 :cc -c -o xxx.o xxx.c 来产生。换句话说 在make 标准库里面必然提供了如下规则:

%.o : %.c
	$(CC) -c -o $@ $^

而 cc 变量也是 make 标准库中的定义的变量。

三.深入理解隐式规则

当make发现目标的依赖不存在时:

    尝试通过依赖名逐一查找隐式规则。

    并且通过依赖名推导可能需要的源文件。

隐式规则的副作用:

编译行为难以控制,大量使用隐式规则可能产生意想不到的编译行为。

编译效率低下:

make从隐式规则和自定义规则中选择最终使用的规则。

隐式规则链:

当依赖的目标不存在时,make会极力组合各种隐式规则对目标进行创建,进而产生意料之外的编译行为。

总结:

隐式规则可能造成意想不到的编译行为。

在实际工程项目中尽量不使用隐式规则。

后缀规则是一种旧式的模式规则。

后缀规则正逐步被模式规则取代。

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

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

相关文章

春节:当代发展及创新传承

为了解中国传统节日——春节,2024年2月9日,曲阜师范大学计算机学院“古韵新声,格物致‘知’”实践队队员贾宣在山东省青岛市西海岸新区的商场中进行了街头调查,探究春节的发展与当代意义。 春节历史悠久,起源于早期人…

vue-内置组件-Suspense

Suspense (实验性功能) <Suspense> 是一项实验性功能。它不一定会最终成为稳定功能&#xff0c;并且在稳定之前相关 API 也可能会发生变化。 <Suspense> 是一个内置组件&#xff0c;用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌…

k8s 部署java应用 基于ingress+jar包

k8 集群ingress的访问模式 先部署一个namespace 命名空间 vim namespace.yaml kind: Namespace apiVersion: v1 metadata:name: ingress-testlabels:env: ingress-test 在部署deployment deployment是pod层一层封装。可以实现多节点部署 资源分配 回滚部署等方式。 部署的…

以管理员权限删除某文件夹

到开始菜单中找到—命令提示符—右击以管理员运行 使用&#xff1a;del /f /s /q “文件夹位置” 例&#xff1a;del /f /s /q "C:\Program Files (x86)\my_code\.git"

【Java八股面试系列】JVM-内存区域

目录 Java内存区域 运行时数据区域 线程独享区域 程序计数器 Java 虚拟机栈 StackFlowError&OOM 本地方法栈 线程共享区域 堆 GCR-分代回收算法 字符串常量池 方法区 运行时常量池 HotSpot 虚拟机对象探秘 对象的创建 对象的内存布局 句柄 Java内存区域 运…

P3647 题解

文章目录 P3647 题解OverviewDescriptionSolutionLemmaProof Main Code P3647 题解 Overview 很好的题&#xff0c;但是难度较大。 模拟小数据&#xff01;——【数据删除】 Description 给定一颗树&#xff0c;有边权&#xff0c;已知这棵树是由这两个操作得到的&#xff1…

Hexo更换Matery主题

引言 在数字化时代&#xff0c;拥有一个个人博客已经成为许多人展示自己技能、分享知识和与世界互动的重要方式。而在众多博客平台中&#xff0c;Hexo因其简洁、高效和易于定制的特点而备受青睐。本文将详细介绍如何为你的Hexo博客更换主题&#xff0c;让你的个人博客在互联网…

LabVIEW工业监控系统

LabVIEW工业监控系统 介绍了一个基于LabVIEW软件开发的工业监控系统。系统通过虚拟测控技术和先进的数据处理能力&#xff0c;实现对工业过程的高效监控&#xff0c;提升系统的自动化和智能化水平&#xff0c;从而满足现代工业对高效率、高稳定性和低成本的需求。 随着工业自…

机器学习:回归决策树(Python)

一、平方误差的计算 square_error_utils.py import numpy as npclass SquareErrorUtils:"""平方误差最小化准则&#xff0c;选择其中最优的一个作为切分点对特征属性进行分箱处理"""staticmethoddef _set_sample_weight(sample_weight, n_samp…

Flask基础学习

1.debug、host、port 模式修改 1) debug模式 默认debug模式是off&#xff0c;在修改代码调试过程中需要暂停重启使用&#xff0c;这时可修改on模式解决。 同时在debug模式开启下可看到出错信息。 下面有关于Pycharm社区版和专业版修改debug模式的区别 专业版 社区版&#…

3.1 Verilog 连续赋值

关键词&#xff1a;assign&#xff0c; 全加器 连续赋值语句是 Verilog 数据流建模的基本语句&#xff0c;用于对 wire 型变量进行赋值。&#xff1a; 格式如下 assign LHS_target RHS_expression &#xff1b; LHS&#xff08;left hand side&#xff09; 指赋值操作…

Go语言每日一题——链表篇(七)

传送门 牛客面试笔试必刷101题 ----------------删除链表的倒数第n个节点 题目以及解析 题目 解题代码及解析 解析 这一道题与昨天的题目在解题思路上有一定的相似之处&#xff0c;都是基于双指针定义快慢指针&#xff0c;这里我们让快指针先走n步&#xff0c;又因为n一定…

[Angular 基础] - 自定义事件 自定义属性

[Angular 基础] - 自定义事件 & 自定义属性 之前的笔记&#xff1a; [Angular 基础] - Angular 渲染过程 & 组件的创建 [Angular 基础] - 数据绑定(databinding) [Angular 基础] - 指令(directives) 以上是能够实现渲染静态页面的基础 之前的内容主要学习了怎么通过…

C语言-3

定义指针 /*指针的概念:1.为了方便访问内存中的内容&#xff0c;给每一个内存单元&#xff0c;进行编号&#xff0c;那么我们称这个编号为地址&#xff0c;也就是指针。2.指针也是一种数据类型&#xff0c;指针变量有自己的内存&#xff0c;里面存储的是地址&#xff0c;也就是…

VMware17上安装centos7.9

一、下载安装包&#xff1a; 1、VMware安装 VMware 下载地址&#xff1a; https://www.vmware.com/cn/products/workstation-pro.html VMware下载后安装即可 安装教程可以参考VMware安装教程 2、CentOs7.9下载地址&#xff1a; http://mirrors.aliyun.com/centos/7.9.2009/iso…

HTML+CSS:全景轮播

效果演示 实现了一个简单的网页布局&#xff0c;其中包含了五个不同的盒子&#xff0c;每个盒子都有一个不同的背景图片&#xff0c;并且它们之间有一些间距。当鼠标悬停在某个盒子上时&#xff0c;它的背景图片会变暗&#xff0c;并且文字会变成白色。这些盒子和按钮都被放在一…

如何用Hexo搭建一个优雅的博客

引言 在数字化时代&#xff0c;拥有一个个人博客已经成为许多人展示自己技能、分享知识和与世界互动的重要方式。而在众多博客平台中&#xff0c;Hexo因其简洁、高效和易于定制的特点而备受青睐。本文将详细介绍如何从零开始搭建一个Hexo博客&#xff0c;让你的个人博客在互联…

Git版本与分支

目录 一、Git 二、配置SSH 1.什么是SSH Key 2.配置SSH Key 三、分支 1.为什么要使用分支 2.四个环境及特点 3.实践操作 1.创建分支 2.查看分支 3.切换分支 4.合并分支 5.删除分支 6.重命名分支 7.推送远程分支 8.拉取远程分支 9.克隆指定分支 四、版本 1.什…

Linux操作系统基础(三):虚拟机与Linux系统安装

文章目录 虚拟机与Linux系统安装 一、系统的安装方式 二、虚拟机概念 三、虚拟机的安装 四、Linux系统安装 1、解压人工智能虚拟机 2、找到解压目录中的node1.vmx 3、启动操作系统 虚拟机与Linux系统安装 一、系统的安装方式 Linux操作系统也有两种安装方式&#xf…

蓝桥杯每日一题------背包问题(一)

背包问题 阅读小提示&#xff1a;这篇文章稍微有点长&#xff0c;希望可以对背包问题进行系统详细的讲解&#xff0c;在看的过程中如果有任何疑问请在评论区里指出。因为篇幅过长也可以进行选择性阅读&#xff0c;读取自己想要的那一部分即可。 前言 背包问题可以看作动态规…