【Linux】Makefile文件

1.Makefile的作用

Makefile文件定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,可以实现自动化编译,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

2. Makefile文件命名和规则

命名为makefile或者Makefile。规则为:

目标....:依赖...
	命令(Shell命令)  //(前面有个缩进)
	...

目标:最终要生产的文件
依赖:生产目标所需要的文件
命令:通过执行命令对依赖操作生成目标(前面必须Tab缩进)

3.自己制作Makefile

//fun1.c
void fun1(void) {
	printf("this is fun1!\n");
}

//fun2.c
void fun2(void) {
	printf("this is fun2!\n");
}

//head.h
#include<stdio.h>
void fun1(void);
void fun2(void);

//test.c
#include<stdio.h>
#include "head.h"

//main.c
int main(){
        //test
        fun1();
        fun2();
        fun1();
        return 0;
}

在这里插入图片描述
存在这样四个文件, main.c函数里面调用了head.h的两个函数。

vim makefile

创建makefile文件,输入相关编译命令。

app:fun1.c fun2.c main.c
	gcc fun1.c fun2.c main.c -o app 

在这里插入图片描述
-o表示将前面的文件生成可执行文件app。

make

输入make命令,执行makefile文件,生成可执行文件app。
在这里插入图片描述
可以看到,终端会自动执行makefile里面的语句。这里只有一句编译命令,看不出makefile有多方便,但是当大型工程中编译命令有上百行的时候,只需要一句make就可以输出上百行编译命令,就会特别方便。
在这里插入图片描述

4. 工作原理

4.1 检查依赖

在这里插入图片描述
在执行命令之前,需要先检查规则中的依赖(红色框)是否存在。如果存在,执行命令;如果不存在,向下检查其他规则,检查是否存在一个规则用来生成该依赖,如果找到了,则执行该规则中的命令。看下面这样一个例子(版本2)。
在这里插入图片描述
.o文件是汇编之后得到的文件,但是还没有进行链接,只有进行了链接才能生成可执行文件。
-c命令能够编译、汇编指定的c文件,生成.o文件,但是不进行链接。

makefile文件一共存在四条规则。当检查第一条规则的依赖时,发现这些.o文件都不存在,就会向下检查其他规则,发现存在规则生成.o文件,所以执行规则中的命令。
在这里插入图片描述
通过命令行能发现,make先执行了生成.o文件的下面三条规则,以便生成第一条的依赖,然后再执行第一条规则生成可执行文件。

4.2 检查更新

在执行规则中的命令是,会比较目标和依赖文件的时间。如果依赖的时间比目标的时间晚,需要重新生成目标。如果依赖的时间比目标的时间早,目标则不需要更新,对应规则中的命令不需要被执行。
在这里插入图片描述
当我们再次执行make,显示可执行文件app已经是最新的。接下来简单修改下main.c文件,中间随便加点注释,再次执行make。
在这里插入图片描述
会发现make命令执行了生成main.o的规则以及生成app的规则。这是因为对于main.o :main.c,因为main.c发生修改,文件的时间会更新,所以变成依赖main.c的时间比目标main.o的时间晚,需要重新生成目标。对于生成app的规则同理。

所以要合理利用这条规则,可以将编译分为多条规则(上面的版本2)执行,而不是一条规则(上面的版本1)。如果仅有一条规则,只要其中一个依赖发生改变,就会全部重新编译。

5. makefile中的变量

预定义变量

  • AR:归档维护程序的名称,默认值为ar
  • CC:C编译器的名称,默认值为cc
  • CXX:C++编译器的名称,默认值为g++
  • $@:目标的完整名称
  • $<:第一个依赖文件的名称
  • $^:所有的依赖文件

自定义变量:变量名=变量值
获取变量的值:$(变量名)

通过修改获得makefile第3个版本,通过定义变量,获取变量。
在这里插入图片描述

6.模式匹配

%.o : %.c

%:通配符,匹配一个字符串;两个%对应的是同一个字符串

当执行第一条规则,发现.o文件不存在,就会去检查下面的规则是否能生成该依赖。对于模式匹配,只要符合条件,就能执行。
在这里插入图片描述
第二条模式匹配规则是,将依赖.c文件生成目标.o文件,命令行中 ( C C ) 代 表 获 取 C 编 译 器 , (CC)代表获取C编译器, (CC)C<代表获取第一个依赖的名称,$@代表获取目标的完整名称。运行后可以正常执行。
在这里插入图片描述

7.函数

$(wildcard PATTERN...)

功能:获取指定目录下指定类型的文件列表,PATTERN代表目录,如果有多个目标,一般使用空格间隔。

$(patsubst <pattern>, <replacement>, <text>)

功能:查找 中的单词(单词以“空格”、“Tab”、“换行”分隔)是否符合模式,如果匹配,则以替换。

可以包括通配符“%”,表示任意长度的字符串。如果想要实际使用普通的“%”,前面需要加转义字符,“%”。
在这里插入图片描述
修改获取第四个版本。对于第一条规则,我们需要的是.o文件,但是.o文件目前还没有生成,所以必须先通过函数获取.c文件,再进行替换获取.o文件。

src变量代表获取当前目录下所以的.c文件,即fun1.c、fun2.c、main.c。

objx变量代表,将刚才获取的src变量(所以.c文件),找到符合%.c的那部分,然后替换成%.o,实际上就是得到了fun1.o、fun2.o、main.o。
在这里插入图片描述
重新执行make,运行成功。
在这里插入图片描述

通过ls命令可以发现make生成了很多中间.o文件,这些中间文件是为了生成最终的可执行文件,但是生成之后就没啥用的。所以可以加上rm命令删除掉。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值