Makefile初探
背景
如果做过工程,或者读过一些优秀的开源代码的话;了解.c文件需要分开写,每个.c文件实现特定的一小部分功能,另外还有一些.h文件,这种文件主要引用一些头文件,声明一些函数(虽然函数可以直接定义无需声明,但是先声明再定义是一个好习惯,另外一些虚函数是仅仅声明而不定义的)与宏;这些.c文件再被不同的目录组织;以上就是工程一般的框架,这些.c文件既可能依赖.h文件,也可能依赖其他.c文件,单单一行gcc的编译命令已经解决不了,这时需要Makefile来指导编译过程!
语法规则
目标文件:依赖文件
|tab|编译规则
注:|tab|代表一个tab键
Demo
我的文件组织如下:1
2
3
4
5
6
7
8
9
10.
├── include
│ └── head.h
├── Makefile
└── src
├── add.c
├── div.c
├── master.c
├── mul.c
└── sub.c
head.h的代码如下:1
2
3
4
5
6
7
8
9
int add(int a,int b);
int sub(int a,int b);
long mul(long a,long b);
float div(float a,float b);
add.c的代码如下:1
2
3
4
5
6
int add(int a,int b)
{
return a+b;
}
差不多这个意思,其他的代码就自己完善吧;
最后master.c代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main()
{
int a,b;
a=12;
b=3;
printf("%d add %d = %d\n",a,b,add(a,b));
printf("%d sub %d = %d\n",a,b,sub(a,b));
long ma,mb;
ma=12;
mb=3;
printf("%ld mul %ld = %ld\n",ma,mb,mul(ma,mb));
float fa,fb;
fa=12;
fb=3;
printf("%f div %f = %f\n",fa,fb,div(fa,fb));
return 0;
}
下面是Makefile文件:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15master:rely1.o rely2.o rely3.o rely4.o rely5.o
gcc -o master src/add.o src/sub.o src/mul.o src/div.o src/master.o
rely1.o: src/master.c include/head.h
gcc -c -I include src/master.c -o src/master.o
rely2.o: src/add.c include/head.h
gcc -c -I include src/add.c -o src/add.o
rely3.o: src/sub.c include/head.h
gcc -c -I include src/sub.c -o src/sub.o
rely4.o: src/mul.c include/head.h
gcc -c -I include src/mul.c -o src/mul.o
rely5.o: src/div.c include/head.h
gcc -c -I include src/div.c -o src/div.o
clean:
find . -name '*.o' | xargs rm -f
下面make生成可执行文件:1
2
3
4
5
6
7
8$ make && make clean
gcc -c -I include src/master.c -o src/master.o
gcc -c -I include src/add.c -o src/add.o
gcc -c -I include src/sub.c -o src/sub.o
gcc -c -I include src/mul.c -o src/mul.o
gcc -c -I include src/div.c -o src/div.o
gcc -o master src/add.o src/sub.o src/mul.o src/div.o src/master.o
find . -name '*.o' | xargs rm -f
make clean会执行Makefile文件中clean下的命令,它会清除所有的目标文件(.o文件),因为已经不需要了!
我们测试一下可执行文件是否正确执行:1
2
3
4
5$ ./master
12 add 3 = 15
12 sub 3 = 9
12 mul 3 = 36
12.000000 div 3.000000 = 4.000000
注:可以看到Makefile中的rely1.o等等只是代号,真正目标文件的名称设定由编译规则指定。