Linux项目自动化构建工具

一.背景

  • 会不会写makefile,从侧面说明了一个人是否具备完成大型工程的能力。

  • 一个工程中的源文件不计其数,按照类型,功能,模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。

  • makefile带来的好处就是–“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

  • make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

  • make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

二.实例

首先我们要使用makefile,我们就得创建一个makefile文件,makefile或者Makefile都可以,允许首字母大写或者小写。

使用touch makefile命令,创建出makefile文件,或者直接使用vim makefile也可以创建出makefile文件。

向下面这样的一个代码,我们不想使用gcc得到可执行程序,而直接使用make命令来得到可执行程序。

源文件:

 #include<stdio.h>
  2 int main()
  3 {
  4     printf("makefile自动化构建\n");                                                          
  5     return 0;
  6 }

makefile文件

mybin:test.c
    gcc test.c -o mybin 

image-20240607160140112

可以看出,使用了makefile文件,就不需要我们使用gcc生成可执行程序了,使用make命令就可以得到可执行程序。

1.依赖关系

image-20240607160825100

makefile文件的语法:首先写的是可执行程序的名字,然后接着:源文件。

2.依赖方法

image-20240607161300002

依赖方法就是我们要执行的操作,很明显,这里的依赖方法就是gcc编译可执行程序的命令。

注意:依赖方法是按键盘上的TAB键,然后再写后面的语句。

关于依赖关系和依赖方法的理解:

人在这世界上不是一座孤岛,你一定和某些人,某些事等存在着紧密的联系。这样才能很好的完成一件事。

比如说,你的老妈和你就是依赖关系,一定是你老妈叫你去打扫卫生(正确的依赖方法),而不是你去叫你老妈去打扫卫生(错误的依赖方法)。也不可能是别人的老妈叫你打扫卫生,你们都不认识,你当然不会做了(错误的依赖关系)。

所以说,做好一件事情,要有正确的【依赖关系】和【依赖方法】。

当然依赖方法也可以不这么写,我们可以把源文件生成可执行程序的过程写成预处理,编译,汇编,链接。

mybin:test.o
   	gcc test.o -o mybin    #链接 
test.o:test.s
  	gcc -c test.s -o test.o    #汇编 -c
test.s:test.i 
	gcc -S test.i -o test.s    #编译 -S
test.i:test.c
  	gcc -E test.c -o test.i    #预处理 -E                        

image-20240607164756029

三.实现的原理

make是如何工作的呢?(统一用上面的例子)

①make会在当前目录中查找makefile或者Makefile的文件。

②如果找到,它会找文件中第一个文件,也就是mybin文件,将这个文件作为最终的目标文件。

③mybin依赖的文件test.o是不存在的,那么make会去找test.o的文件,依次类推去找,最后再倒回来执行(像是调用堆栈的过程)

image-20240607165925395

④ 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。

⑤make只管文件的依赖性,如果冒号后面没有文件的话,make就不工作了。

image-20240607170507233

四.项目清理

当一个目录中我们进行各种操作,出来很多文件,我们想要删除这些文件,每次需要我们手动删除这些文件吗?显得很麻烦,于是我们一样可以使用makefile文件自动化删除这些文件。

命令:make clean

语法:

.PHONY:clean  #这个待会说
clean:                                                                                
	rm -f test.o test.s test.i mybin

clean:是依赖关系,换行加上TAB键,这一行是依赖方法。

image-20240607172009458

这里make和makefile配合使用,就可以实现创建文件,然后删除文件。

五. .PHONY是什么?

.PHONY是一个伪目标,makefile中将.PHONY放在一个目标前,就表示这个目标是一个伪目标。

那.PHONY有什么作用呢?

1.PHONY的作用

防止在makefile中定义的执行命令的目标和工作目录下的实际文件出现名字冲突。

也就是clean前有.PHONY,那么clean操作就可以一直反复执行,一直可以执行它的依赖方法

image-20240607190534051

这里我们可以一直执行make clean操作,其实第一次make clean操作我们就已经完成文件的删除了,但是还是可以继续执行该命令。

2.PHONY的原理

.PHONY修饰的clean,clean后面的依赖关系为空,.PHONY修饰的目标clean并不是某个依赖项生成的实际文件,因此make不会在当前目录去搜索是否有clean文件。

其实对于clean来说,不加.PHONY修饰也可以实现一直make clean操作,就是因为它依赖的对象为空,生成clean文件时,不需要某些文件必须存在。

没有伪目标:

image-20240607191625222

image-20240607190534051

得到的结果是一样的。

我们知道make操作一次了之后,就不能在继续操作了,这是因为该目录下已经存在该文件了,是最新的文件,除非文件的acm时间变了,我们是不是可以在make前加上.PHONY,也可以一直执行make命令。

image-20240607192347374

image-20240607192326878

当然,结果达到了我们的预期。

为什么make不加.PHONY伪目标,就无法连续多次的使用make呢?这里我们就要探讨一下make的判断机制了。

六.make的判断机制:文件的ACM时间

当我们使用ll命令,查看文件的信息时,会出现一个时间,该时间是最近文件修改的时间,这个时间也叫Modify time。

image-20240607194420155

文件其实还有两个时间Access time和Change time,使用命令【stat+文件名】查看。

image-20240607194723465

1.Access time

Access time简称atime,这是目录或文件最后一次访问的时间。

使用命令cat可以查看文件的内容,也就是访问了文件,那么atime时间就会改变。

image-20240608123453474

可以看出,使用了cat命令查看文件的内容后,文件的atime并没有修改,这是为什么呢?

一般而言,一个文件被访问的频率是很高的,我们看到的文件都是在磁盘存放着的,如果我们每次访问文件,都要修改atime,其实就是访问磁盘,如果linux中充斥着大量的访问磁盘的IO操作,变相的减慢系统的效率。

故而修改文件的atime,添加了【次数限制】。

2.Modify time

Modify time简称mtime,这是目录或文件最后一次被修改的时间。

修改文件的内容,mtime的时间自然会改变,但是这里的修改不是指只有文件的内容修改了才是修改,不是说文件的内容不改变它就不会变,而是文件是否进行了写操作

比如,我们使用vim打开一个文件,然后我们不修改文件的内容,而使用wq来退出文件。

image-20240608125212433

可以看出确实如此。mtime和文件是否进行了写操作相关。

回到之前,make是如何知道这是一个最新的文件,从而不能多次使用make命令,其实就是比较文件的mtime来看的。

解释:刚开始一定是先有的源文件,使用make命令创建除了可执行程序,源文件时间<可执行程序时间,再次使用make命令就无法实现,因为可执行程序此时就是最新的文件。

​ 但是,当我们对文件执行了写操作的话,源文件的时间就变成了:源文件时间>可执行程序时间,于是此时的源文件就变成了最新的文件,于是就可以继续执行make命令来生成可执行程序。

3.Change time

Change time简称ctime,这是对文件Inode信息最后修改时间。

I 什么是Inode?

理解inode,要从文件储存说起。
文件储存在硬盘上,硬盘的最小存储单位叫做“扇区”(Sector)。每个扇区储存512字节(相当于0.5KB)。
操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个“块”(block)。这种由多个扇区组成的“块”,是文件存取的最小单位。“块”的大小,最常见的是4KB,即连续八个 sector组成一个 block。
  文件数据都储存在“块”中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为“索引节点”。

II Inode中的内容?

  • 文件的字节数
  • 文件拥有者的User ID
  • 文件的Group ID
  • 文件的读、写、执行权限
  • 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
  • 链接数,即有多少文件名指向这个inode
  • 文件数据block的位置

总之,除了文件名以外的所有文件信息,都在存在Inode中。

七.makefile的小招

1.简化makefile写法

正常的写法:

mybin:test.c
	gcc test.c -o mybin 
.PHONY:clean
clean:
	rm -f mybin 

简化的写法①:

mybin:test
	gcc $^ -o $@
.PHONY:clean
clean:
	rm -f mybin 

这里使用$^来代替源文件,也就是依赖文件;$@来代替可执行程序,也就是目标文件。

简化的写法②:

mybin:test
	gcc -o $@ $^
.PHONY:clean
clean:
	rm -f mybin 

只需要保证-o的后面保证是$@即可。

简化的写法③:

cc=gcc
src=test.c
target=mybin
$(target):$(src)
	cc -o $@ $^
.PHONY:clean
clean:
 	rm -f $(target)

2.不显示makefile代码

image-20240608133708214

每次我们使用make或者make clean命令时,它都会把该命令打印出来,可以在makefile中的代码前加上一个@即可,这样每次就不回显了。

mybin:test.c
	@gcc  -o $@ $^ 
.PHONY:clean
clean:
	@rm -f mybin

image-20240608134011937

  • 11
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值