04makefile学习之多个规则处理多个文件
以下为相关makefile的学习文章
01makefile学习之GCC编译的四个阶段(带编译阶段、汇编阶段、-S,-c的区别)
02makefile学习之makefile的基本原则
03makefile学习之makefile的一个规则
04makefile学习之多个规则处理多个文件
05makefile学习之两个函数和一个特殊规则clean
06makefile学习之三个自动变量(@ , @,@,^,$<)和模式规则
07makefile学习之习题1
08makefile学习之习题2
1 明明一个规则可以将一个或者多个文件生成可执行文件,为什么要用多个规则处理多个文件?
根据上一篇我们知道如何使用一个规则来进行最简单的makefile编译生成可执行程序。这一篇讲多个规则处理多个文件,那么为何要这样做呢,假设这里有add.c,sub.c,mul.c,hello.c,我们需要将其生成可执行文件,那么一条规则的话,很简单,如下:
hello:hello.c add.c sub.c mul.c
gcc hello.c add.c sub.c mul.c -o hello
简单吧,但是现在如果我们某个文件需要更新改动呢?假设add.c改动,那么重新执行的话sub.c,hello.c,mul.c都要重新编译汇编链接,那不是非常麻烦吗?它们都不需要更新但是却要重新编译,非常浪费时间。
所以人们就想出办法将其进一步拆分成多个规则,当某个文件改动时只编译它自己即可。
2 例子
下面有主文件hello.c,其内部调用add.c,sub.c,mul.c三个文件内的方法,利用makefile将其生成可执行文件hello。
hello.c:
#include<stdio.h>
int add(int,int);
int sub(int,int);
int mul(int,int);
int main(){
int a=10;
int b=5;
printf("%d+%d=%d\n",a,b,add(a,b));
printf("%d-%d=%d\n",a,b,sub(a,b));
printf("%d*%d=%d\n",a,b,mul(a,b));
return 0;
}
add.c:
int add(int a,int b){
return a+b;
}
sub.c:
int sub(int a,int b){
return a-b;
}
mul.c:
int mul(int a,int b){
return a*b;
}
makefile:
hello:hello.o add.o sub.o mul.o
gcc hello.o add.o sub.o mul.o -o hello
hello.o:hello.c
gcc -c hello.c -o hello.o
add.o:add.c
gcc -c add.c -o add.o
sub.o:sub.c
gcc -c sub.c -o sub.o
mul.o:mul.c
gcc -c mul.c -o mul.o
这样当我们只修改add.c时,他只会执行add.o:add.c那行规则,然后再执行生成hello可执行文件那组规则,减少了生成hello.o,sub.o,mul.o三组规则。
注意:有同学可能以为第一组规则不执行,它是会执行的,即加快速度我们是针对编译而言(以为其它三个没有用-c编译嘛),链接它照样会执行(第一组)。
3 makefile中默认生成的最终文件
在上面的makefile中,最终生成hello,因为make第一行默认是最终生成文件。
例如我们将第一组规则移到最底部,会发生什么?
结果是make工具只会生成hello.o,因为移动后第二行变成第一行,然后根据该规则已经完全可以生成hello.o,所以只会生成hello.o。
那么我们可以用什么办法解决默认呢?
可以使用ALL(小写也行)。例如;
#ALL代表指定要生成的最终文件
#"-c":代表只编译并且在汇编阶段只生成目标文件后跳过汇编和链接
ALL:hello.o
hello:hello.o add.o sub.o mul.o
gcc hello.o add.o sub.o mul.o -o hello
hello.o:hello.c
gcc -c hello.c -o hello.o
add.o:add.c
gcc -c add.c -o add.o
sub.o:sub.c
gcc -c sub.c -o sub.o
mul.o:mul.c
gcc -c mul.c -o mul.o