Makefile基础教程(make的隐式规则)

news2024/10/7 20:34:03

文章目录

  • 前言
  • 一、什么是make的隐式规则
  • 二、makefile中出现同名目标时
  • 三、一些常见的隐式规则
  • 四、查看隐式规则
  • 五、隐式规则缺点
  • 六、禁用隐式规则
    • 1.全局禁用
    • 2.局部禁用
  • 总结


前言

本篇文章将给大家介绍make的隐式规则。

一、什么是make的隐式规则

Make 的隐式规则是指 Make 在没有找到显式规则的情况下,会自动使用的一组规则。这些规则是预定义好的,可以被 Make 自动识别和调用,不需要用户指定具体的规则。

隐式规则的使用可以大大简化 Makefile 的编写,特别是当需要编译大量源文件时。隐式规则可以根据不同的文件扩展名自动调用不同的编译命令。

二、makefile中出现同名目标时

在 Makefile 中,如果出现了同名的目标,则后面出现的目标会覆盖前面同名的目标。这种情况可能会导致不可预期的错误,因此需要特别注意。

例如,以下 Makefile 中存在两个同名的目标 all:

all: target1
    @echo "build complete"

target1:
    @echo "building target1"

all: target2
    @echo "build complete"
    
target2:
    @echo "building target2"

在这个 Makefile 中,第二个 all 目标将覆盖前面的 all 目标,因此执行 make 命令时只会编译执行第二个all中的命令,而不会执行第一个all中的命令。

执行结果:
在这里插入图片描述

三、一些常见的隐式规则

大家觉得下面的makefile可以正确执行吗?在这里我们并没有生成对应的.o文件。

SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)


hello : $(OBJS)
	$(CC) -o $@ $^
	@echo craet file ok

执行结果:
执行结果却出乎我们的意料,明明没有生成对应的.o文件啊,为什么还是正确执行呢?这就是因为make的隐式规则。

在make中包含这样的一条隐式规则:C 源文件编译为目标文件:%.o: %.c。
当make发现没有对应的规则时就会调用到这个隐式规则。
在这里插入图片描述

四、查看隐式规则

使用make -p命令可以查看隐式规则:
这里隐式规则是有非常多的,这里就不一 一进行讲解。
在这里插入图片描述

五、隐式规则缺点

虽然隐式规则可以方便地简化 Makefile 的编写工作,但是使用隐式规则也存在一些缺点:

可能导致编译错误:隐式规则会自动推导源文件和目标文件之间的关系,但不一定符合实际情况。如果隐式规则的规则不适合当前项目的情况,则可能导致编译错误。

难以定制要求:隐式规则通常是基于一些默认的编译选项,而这些选项可能不符合用户的需求。通过隐式规则,用户难以对编译选项进行修改和自定义配置。

可读性较差:隐式规则隐藏了 Makefile 的具体细节,使 Makefile 更加难以理解和调试。由于隐式规则并不直接体现在 Makefile 中,因此难以准确理解每个目标和规则之间的关系。

综上所述,隐式规则虽然提高了 Makefile 编写的效率和可读性,但在一些情况下可能会导致编译错误、难以定制编译选项和可读性差等问题。因此,对于较大和复杂的项目,最好使用显式规则来更加精确地控制编译过程和生成的目标文件。

六、禁用隐式规则

1.全局禁用

使用make -r命令全局禁用隐式规则:

这里使用make -r命令来执行上面编写的makefile:

执行结果:
从结果可以看出隐式规则被禁用了,没有起作用了。
在这里插入图片描述

2.局部禁用

局部禁用的方法就是定义自己的规则和变量。
修改代码后:

CC := gcc

SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)


hello : $(OBJS)
	$(CC) -o $@ $^
	@echo craet file ok

$(OBJS) : %.o : %.c
	$(CC) -o $@ -c $^
	@echo this is myrule

运行结果:
在这里插入图片描述
跟上面的运行结果做一个对比后就知道在定义了自己的规则后就不会使用到make里面的隐式规则了。

总结

本篇文章我们介绍到了make中的隐式规则,使用隐式规则可以帮助我们节省代码的编写量,但是有的时候却会出现意想不到的错误,使用局部禁用和全局禁用的方法可以让make不使用隐式规则,希望大家牢牢记住这篇文章的内容防止以后在开发中遇到问题。

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

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

相关文章

css选择器及其权重

1. 类型选择器 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-wid…

【ZYNQ】裸机 PS + PL 双网口实现之 ZYNQ 配置

目前&#xff0c;在 ZYNQ 中进行以太网开发的方案&#xff0c;大部分都是基于通过 PS 的 MIO 以 RGMII 接口连接外部 PHY 芯片的方式。但是&#xff0c;由于使用 PS 的 MIO 只能以 RGMII 接口连接外部 PHY 芯片&#xff0c;这就限制了支持其他接口 PHY 芯片的使用&#xff0c;如…

分文件实现温湿度数据管理系统项目

目标&#xff1a; 了解分文件的概念&#xff0c;要依次从C语言的函数声明、变量的存储类别、C语言编译预处理&#xff0c;说起。这些知识点我们之前或多或少接触过&#xff0c;这里做个总结与拓展。经过总结&#xff0c;最后我们归纳出一个实现C语言模块化编程的技巧&#xff…

03-bootstrap-响应式布局-栅格系统

一、概述 1、栅格系统是 Bootstrap 中响应式布局的重要组成部分&#xff0c;旨在实现页面元素的自适应排版。Bootstrap 栅格系统将屏幕宽度分为 12 列&#xff0c;通过在 HTML 元素上添加相应的类名&#xff0c;可以让元素占据指定数量的列数&#xff0c;从而实现灵活的布局效…

5种易实现的Linux和 Windows VPS速度提升方法

​  无论是Linux VPS还是Windows VPS&#xff0c;网站速度的提高都是非常重要的。它们在提高网站速度方面都有很多的优化方法。下面我们将介绍 5 种提高网站速度的方法。 1.通过缓存加速 缓存通常是用来加快商业网站加载时间的技术&#xff0c;因此它也可以用在 VPS 上。没有…

车架号查车辆信息-vin查车辆信息api接口

接口地址&#xff1a; https://登录后显示/pyi/88/264(支持:http/https)) 在线查询&#xff1a;https://www.wapi.cn/car_vin.html 网站地址&#xff1a;https://www.wapi.cn 返回格式&#xff1a;json,xml 请求方式&#xff1a;GET,POST 请求说明&#xff1a; Md5验证方式-…

字符串、字符串列表,倒序生成字典。

带数字的字符串以数字为key倒序生成字典&#xff0c;字符串列表按其元素索引为key倒序生成字典。 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那么简…

【MySQL】-- 表的操作

目录 表的操作 创建表 创建表案例 查看表结构 查看表结构案例 查看历史上表的创建语句 修改表 修改表实例 新增列属性 修改列属性 删除列属性 修改列名 修改表名 删除表 表的操作 创建表 语法&#xff1a; CREATE TABLE (if not exists) table_name (fie…

【MyBatisPlus框架】

文章目录 MyBatisPlus1.概述1.1 简介1.2特性1.3支持数据库1.4框架结构 2.入门案例2.1 创建数据库以及表2.2 创建工程2.2.1引入依赖 2.3编写代码 3.基本CRUD3.1BaseMapper3.2插入3.3删除3.4修改3.5查询3.6通用Service 4.常用注解4.1TableName4.1.1问题4.1.2通过TableName解决上述…

简述springmvc的流程

4、SpringMVC的执行流程 用户向服务器发送请求&#xff0c;请求被SpringMVC 前端控制器 DispatcherServlet捕获。 DispatcherServlet对请求URL进行解析&#xff0c;得到请求资源标识符&#xff08;URI&#xff09;&#xff0c;判断请求URI对应的映射&#xff1a; a) 不存在 …

day05 java_Spring IoC 和 DI

为什么使用spring框架 1.解耦代码(每次使用都要new一个对象) 2.解决事务繁琐问题(创建对象----初始化----调用方法销毁对象) 3.使用第三方框架麻烦的问题 总结:spring是一个轻量级的Ioc,Di和AOP容器 轻量级:简洁,高效,低依赖 **容器:**创建对象并将对象存储对象,同时管理…

高矿化度矿井水深度除氟装置CH-87技术解析

高矿化度矿井水是指含有高浓度溶解性矿物质的废水&#xff0c;通常指的是含有高浓度钠、钙、镁、铁、铝、钾等离子的废水。这些离子通常来自于废水所处的环境、工业或生产过程中使用的原材料和化学品。高矿化度的废水通常具有高盐度、高电导率、高硬度等特征&#xff0c;对环境…

性能测试计划不会写?我告诉你有模板你看不看

目录 1 简介 2 测试进入条件 3 测试退出条件 4 性能测试需求 5 测试风险 6 测试时机 7 测试策略 8 测试资源 9 测试进度 10 交付物 1 简介 1.1 目的 【描述性能测试计划的目的。】 1.2 背景 【描述项目或产品的背景。】 1.3范围 【描述性能测试的整体范围。】 2 测试进入条件 【…

Java如何配置环境变量

Java如何配置环境变量 0. 前言1. 下载Java2. 配置环境变量2.1新建 Java_Home2.2 编辑Path情况1情况2 3. 验证安装 0. 前言 本节记录如何配置Java环境变量&#xff0c;用自己重装过的系统实操 操作系统&#xff1a;Windows10 专业版 Java版本&#xff1a;jdk1.7.0_07 1. 下载…

全网最详细,Selenium自动化测试问题总结+解决,跟着大佬上高速...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Selenium4自动化测…

性能测试工程师必看——性能测试报告模板

目录 1. 测试概述 1.1 测试目标 1.2 指标和术语 2. 环境、工具 2.1 测试环境 2.2 测试工具 3. 测试方案 3.1 测试类型 3.2 业务模型 3.3 加密验签处理 3.4 压力梯度 4. 测试结果 4.1 聚合报告 4.2 系统吞吐量 4.3 资源占用率 5. 分析和建议 5.1 测试结论分析 …

Sqoop伪分布式配置

目录 一、Sqoop下载 二、解压 三、添加环境变量 四、复制sqoop-env-template.sh文件 五、编辑组件路径 六、拷贝Mysql与Hive驱动文件 七、验证 一、Sqoop下载 安装包下载地址&#xff1a;Sqoop 官网 二、解压 解压和重命名文件 tar -zxvf sqoop-1.4.7.bin__hadoop-2.…

006 - STM32学习笔记 - RCC时钟树

006 - STM32学习笔记 - RCC时钟树 本节内容一定要结合RCC时钟树和官方手册学习&#xff0c;如果看不明白的话&#xff0c;建议看一下野火官方的教程&#xff0c;火哥讲这节讲的很详细&#xff0c;看一遍基本就能理解了。 上节内容中分析了启动代码&#xff0c;在启动代码中看…

Redis - Redis16个常见使用场景

1、缓存 String类型 例如&#xff1a;热点数据缓存&#xff08;例如报表、明星出轨&#xff09;&#xff0c;对象缓存、全页缓存、可以提升热点数据的访问数据 作为Key-Value形态的内存数据库&#xff0c;Redis 最先会被想到的应用场景便是作为数据缓存。而使用 Redis 缓存数…

【面试题】操作系统面试实战

version&#xff1a;1.0 文章目录 操作系统进程管理&#x1f64e;‍♂️面试官&#xff1a;进程和线程的区别&#xff1f;&#x1f64e;‍♂️面试官&#xff1a;进程有哪几种状态?&#x1f64e;‍♂️面试官&#xff1a;进程间的通信方式&#xff1f;&#x1f64e;‍♂️面试…