linux自动构建工具make/makefile
文章目录
- linux自动构建工具make/makefile
- 是什么
- 为什么有
- 怎么做
- 依赖关系和依赖方法
- makefile基本语法
- 最佳实践以及细节
- 结语
很高兴和大家见面,给生活加点impetus!!开启今天的编程之路
今天我们来学习Linux的基础构建工具,主要从是什么为什么,怎么做的角度出发,包含细节,示例
作者:٩( ‘ω’ )و260
我的专栏:Linux,C++进阶,C++初阶,数据结构初阶,题海探骊,c语言
欢迎点赞,关注!!
linux自动构建工具make/makefile
是什么
make是一个指令,makefile是一个文件。
我们可以先来见一见大致是怎么做的:
首先需要创建一个makefile普通文件,同时我们还需要一个源文件,我们在makefile文件上这样写:
zxh.exe:zxh.cgcc -o zxh.exe zxh.c
其实第一行是依赖关系,第二行是依赖方法~
随后我们直接make,来看结果:
生成exe文件也是能够运行的~
这里我们先抛出一个结论:
make/makefile其实是一个个脚本语言,make指令能够用来解释当前目录下的makefile文件中的信息
为什么有
因为世界上本来就是依赖关系和依赖方法的相同作用,计算机作为世界的一环,所以也产生了依赖关系和依赖方法~
怎么做
依赖关系和依赖方法
首先,依赖关系其中包含目标文件和依赖文件列表,依赖文件列表可以为空,依赖方法其实就是指令,指令可以是一条,同时也可以是很多条
makefile基本语法
依赖关系写法:
目标文件:(冒号)依赖文件列表
依赖方法写法:
最开始有一个制表符,随后写出指令即可
随后我们来看,在vs中,有一个功能叫清理项目,清理的是什么呢?答案是所有的目标文件以及exe文件,源文件肯定不会被清理~
我们来看实现:
1 zxh.exe:zxh.c
2 gcc -o zxh.exe zxh.c
3
4 .PHONY:clean
5 clean:
6 rm -rf zxh.exe
首先,这里会有几个问题,问题1:PHONY是什么,问题2:效果是什么,问题3:是如何造成这样的效果的呢?,问题4:为什么clean我就要加这个,但是zxh.exe不加这个
PHONY是什么呢?在英语中,该单词表示虚假的,虚伪的,使用PHONY修饰过的目标叫做伪目标,伪目标也是目标。
造成的效果是什么呢?造成的效果是总是被执行的,我们先来看效果:
为什么会是这样的现象呢?其实是被PHONY修饰的结果,这就要谈到PHONY修饰的目标和没PHONY修饰的去区别了。
PHONY修饰的作用:决定了总是被执行,即可以一直通过以来关系推导依赖方法
那么,如果说我们给zxh.exe目标添加PHONY,是不是也能够一直运行了呢?来看结果:
1 .PHONY:zxh.exe 2 zxh.exe:zx exe [ID] 3 gcc -o zxh.exe zxh.c4 5 .PHONY:clean6 clean: 7 rm -rf zxh.exe
我们添加上PHONY之后,发现能够一直执行gcc指令,能够一直生成新的zxh.exe。那么,就又衍生出了一个问题,没有被PHONY修饰时,为什么gcc不允许编译旧的源文件呢?
是为了提高编译效率,这里我只有一个源文件,如果说同时又1000个源文件,但是,我只是对几个源文件进行了修改,难道我就要对所有源文件重新编译一遍吗?这样做的话效率非常低下。所以,这也回答了第四个问题,为了保证编译效率,所以生成exe文件的时候不用添加PHONY,而clean清理文件的时候肯定清理的十分频繁,所以需要添加~
那么效果和作用我们都明白了,底层是怎样达到这样的效果的呢?
先说结论:
底层通过modify时间来比较时间的新旧,进而完成源文件是否需要更新~
modify时间是决定文件内容是否被修改的
先来看如何比较的?
当我们有一个源文件时,此时我们直接编译,生成了一个exe文件,此时exe文件一定是比src文件的modify时间新的,如果说此时我们修改modify,src的modify时间就比exe文件更新,此时有又能够重新编译了!!
我们来验证一下这种结果:
所以,如果我们touch已经存在的文件,就会修改该文件的modify时间
那么,我们扩展讲解一下ACM时间,即access时间,modify时间和change时间。
access时间:当文件本访问时,该时间就会更新
modify时间:当文件内容被修改是,该时间就会更新
change时间:当文件属性被修改时,该时间就会更新
我们来看结果:
我们进行了大小更改,为什么这三个属性全被修改了呢?
因为意料之中的modify时间被修改,但是我修改了文件大小,文件大小的属性被修改,此时change时间肯定也会被修改,同时,我去添加代码的时候访问了这个文件,所以access时间也会被修改。而且,我的modify时间被修改,modify时间能不能也被看做是一种文件属性呢?
接下来我们修改一下change时间:
我们来修改一下access时间,文件被访问其实有很多方式,比如cat,vim等等,来看示例:
其实这里还有一个细节,如果我我现在还去cat,access时间会如何改变呢?
为什么此时access时间没有改变了?
原因为效率问题。
cat查看文件,造成access时间修改,我们要看到access时间修改的话,属性的修改就必须要存入到硬盘之中,如果我们一直cat,操作系统和硬盘之间的交互就会变多,而且硬盘是外部设备,本身效率就慢,加之操作系统频繁和硬盘交互,其他程序运行效率就会降低
结论:当cat访问文件达到一定次数时,access时间就会被修改
最佳实践以及细节
我们先需要讲解一下语法规则,直接来看截图:
在makefile中,有了以上的语法规则,对于编译很多个的源文件已经绰绰有余了。我们需要再来明白一点区别,vs是集成开发环境,一个项目只能够编译成一个exe文件,我们有了自动化构建工具,能够指定哪几个源文件生成什么名字的exe文件~
同时,这里我们可以来写一个万能的makefile文件,能够应对大多数情况:
随后我们来制造有100个源文件的示例:
touch src{1..100}.c//创建src1.c src2.c ...src100.c
此时我们来构建一下:
运行结果:
我们来删除obj文件(临时文件)以及exe文件
这样就大功告成了~~
细节:
1:依赖关系必须存在,依赖文件列表可以为空,表示不依赖任何东西,直接可以执行
2:依赖方法可以是任何shell命令,可以是很多条
3:clean目标,利用了make的自动推导能力,让他执行了rm命令
4:make命令,后面可以跟目标名,后面跟谁就解析谁的依赖关系和依赖文件列表,只有make默认就有解析第一条依赖关系(依赖链)
结语
今天的内容就分享到这里了,感谢大家阅读,不足之处欢迎大家留言指正,感谢大家支持!!
滴水之力,可穿磐石;一念之恒,能移群山!!