当前位置: 首页 > article >正文

初识Linux · 有关makefile

目录

前言:

1 makefile的简单使用

2 makefile介绍


前言:

我们上文介绍了gcc和g++的基本使用,带了许多的子指令,但是有的时候啊,一个一个敲指令确实有点麻烦了,此时,一个工具就能派上用场,即自动化工具makefile。

我们不妨理解为语言中的宏,命令的重新命名都可以通过makefile来表示,这就大大简化了工程量了,所以,有的时候makefile的使用从侧面也决定了工程的完备程序以及效率问题。

通过简单的介绍,我们知道了makefile是一个自动化命令工具,那么使用方法第一个是要创建makefile文件,makefile或者是Makefile都可以,我们在文件里面写入一些指令加上一点操作,我们就可以实现自动化指令了。


1 makefile的简单使用

我们不妨,先看看makefile的简单使用:

第一步是创建一个makefile文件并往里面写入一些指令->后面会介绍。

第二步则是先来一个实例代码:

然后,我们直接make一下,就可以创建一个test的可执行文件了,我们执行也是没有问题的:

其中,clean指令也是可以完成我们的预期操作的。


2 makefile介绍

我们从makefile文件中的第一个点开始:

第一行的test:test.c,其中test:test.c成为构成了依赖关系,test叫做目标文件,test.c是被test依赖的。

其中:后面的叫做依赖文件列表,不同的依赖文件可以用空格进行分割,也可以为空。那么下面的指令就是依赖方法,依赖方法前面只能使用Tab来空位置,不能使用四个空格,会报错。

这的理解我们可以理解为父子,儿子问父亲要钱,这里面存在父子之间的依赖关系,依赖方法是养育,所以给钱。

那么我们如果重复使用该命令呢?

它第一次是成功执行了的,但是后面就告诉说,test is up to date,表明test文件已经是最新文件了。

此时,前面文章埋的伏笔就可以拉出来了->文件的ACM时间

我们首先看看test.c的ACM时间:

这里为什么不让多次执行编译的命令就是因为makefile工具比较的是源文件和可执行文件的ACM时间,如果可执行文件和源文件的ACM时间,在修改上有差别,make检测到源文件更新了,才会重新编译源文件,这样做的目的是提高效率,比如不能总一直编译已经编译好了的文件吧。

以及,不同的自动化工具对于时间的判断是不一样的,比如我们平时使用的VS,有的时候出现bug,重新清理一下解决方案,再运行就可以了,大多数就是因为时间的判断准则出现问题了,此时清空解决方案就是为了更新一下可执行文件的ACM时间,一比较,欸源代码早一点,重新编译就成功了。

但是,前面我们介绍了一个指令叫做touch,是用来创建文件的,好像在这里没有啥用处,但是使用touch可以改变ACM时间:

所以我们想要重复编译也可以使用touch改变ACM时间再进行编译即可。 

此时,再引出一个关键词,.PHONY:

我们会发现clean总是可以执行的,这就是.PHONY做的事,被.PHONY修饰了的指令,默认可以重复执行,所以我们可以重复执行,那么我们同样可以把.PHONY给test修饰了

就可以重复编译了,此时clean也是可以重复执行的,因为clean是特殊的方法,后面也不用跟任何东西:

那么现在来深究原理部分,为什么我们直接make是执行的第一个指令呢?

因为makefile执行方向就是从上往下进行执行的,所以我们直接make,默认执行的是第一个指令,那么我们换个位置:

此时make就是执行的第一个语句了。

此时啊,学到这里,不免会觉得我每次使用指令都要给我打印出来,一点神秘感都没有,能不能不打印呢?

当然是可以的,此时用到的符号是@,@任意的指令,就能让指令不显示出来:

此时make了一下之后,rm -rf之后也没显示:

此时同理。

 

所以@是只能应用一个指令,不是多行的,此时对echo@一下就可以了:

 这里还有一个有意思的点是,makefile里面的注释是#,并且允许变量的存在,虽然说是变量,但是实际上就是宏了:

执行的操作实际上就是替换。

但是这样使用就会导致如上错误。

需要搭配$使用:

此时就没问题了。

这里涉及了替换,我们不妨再看看$@ $^:

不难看出,$@ $^分别代替的是目标文件和依赖文件。

好了,现在又提到了依赖关系,那么,我们看一段代码:

我们不难发现依赖关系是连着的,所以我们可以直接创建编译的三个阶段的文件。

那么既然依赖关系是连着的,试试打乱顺序呢?

 

可以发现,还是可以创建,难道是说随意打乱顺序都没有问题的吗?

当然不是;

此时只能创建预处理期间的文件,可执行文件就创建不了了,凡事都要有一个带头的不是,所以可执行文件要放最开始: 


感谢阅读!


http://www.kler.cn/a/289002.html

相关文章:

  • C++内存池实现
  • debian 系统更新升级
  • 用枚举算法解决LeetCode第3348题最小可整除数位乘积II
  • 如何在Mac上切换到JDK 17开发环境
  • C语言打印时间精确到毫秒
  • JVM 中的完整 GC 流程
  • 【Rust光年纪】化学计算不完全指南:Rust语言库全面解析
  • jenv 一款macos下的开源JAVA多版本环境安装管理切换工具
  • Swift concurrency 5 — async let的理解与使用
  • 聊聊随机测试和猴子测试
  • Python参数传递的艺术:解锁编程灵活性的秘密武器
  • uniapp写的一个年月日时分秒时间选择功能
  • 【数据结构初阶】——栈和队列
  • 求三元组中可能出现的最小距离
  • RabbitMQ练习(Routing)
  • 使用COAP和MQTT协议的多协议方法开发的用于机器人手术的自动医疗物联网系统
  • vue3+ts 实现模板表格文件下载~
  • pikachu文件包含漏洞靶场攻略
  • 密钥分发与公钥认证:保障网络通信的安全
  • MySQL入门学习-MySQL的连接查询
  • MySQL——事务与存储过程(二)存储过程的创建(4)光标的使用
  • 【Linux学习笔记】protobuf相关操作
  • 数仓基础(九):各大公司实时数仓实践
  • Go锁 详解
  • k8s-使用Network Policies实现网络隔离
  • (二)、软硬件全开源智能手表,可全面高精度采集生命体征数据,进行健康检测。(HealthyPi Move)