- 首先我们通过实例来理解makefile的规则
创建两个文件:a.c b.c,在a中调用b函数func_b
//a.c
#include <stdio.h>
int main(){
func_b();
return 0;
}
//b.c
#include <stdio.h>
void func_b(){
printf("This is B\n");
}
这时候我们使用:gcc -o test a.c b.c 可以生成test可执行文件 执行./test输出This is B 程序执行成功
我们知道由一个.c文件到可执行文件中间经历了4个步骤:预处理->编译->汇编->链接。
虽然这个命令很简单,但是它在执行时会对所有的文件都执行4步,当文件很多的时候,就会带来很大的性能问题。对这些文件我们应该分别处理,最后在链接。类似以下方式:
步骤一:gcc -c -o a.o a.c //处理a文件
步骤二:gcc -c -o b.o b.c //处理b文件
步骤三:gcc -o test a.o b.o //最终链接
如果我们只修改了a文件,则只需要执行1、3步骤即可,直接使用旧的b.o文件,这样就省去一些没必要的步骤。
那么问题是我们该如何判断文件是否修改过呢?其实makefile是根据 .c文件是否比 .o文件新(生成或修改时间) 如果新,则重新执行编译,再重新生成test程序
- 编写一个makefile:
- 规则:
目标:依赖1 依赖2 ...
[TAB] 命令
- 规则:
makefille文件:
#如果b.o、a.o比test文件新,则执行下面的命令生成test
test:a.o b.o
gcc -o test a.o b.o
#如果a.c比a.o文件新,则执行下面的命令生成a.o
a.o : a.c
gcc -c -o a.o a.c
#如果b.c比b.o文件新,则执行下面的命令生成b.o
b.o : b.c
gcc -c -o b.o b.c
这个makefile文件包含三条基本规则,
第一次执行make的时候,执行第一个规则,生成test文件,但是需要依赖a.o与b.o,但是没有这两个文件,于是查找其他规则有没有生成这两个的文件的规则,如果有其则执行命令,生成这两个文件,最后执行第一个规则的命令生成test文件。
第二次执行make的时候,发现a.o与b.o都没有比test文件新,则不执行任何命令
当我们修改a.c文件时,再次执行make命令,这时发现a.c比a.o新,则执行规则2的命令生成新的a.o,而b.o没有变化,则执行规则1的命令生成test,所以只执行了1+2步骤。
- 总结下makefile规则:
目标:依赖1 依赖2 ...
[TAB] 命令
当 "目标文件"不存在或某个依赖文件比目标文件新
则:执行"命令"