本文重在记录makefile的使用方法,不介绍相关原理。
注意:所有的makefile指令前面都需要两个 tab 缩进
1.初步使用
创建工作目录,工作目录下创建如下两个文件:
main.c
#include <stdio.h>
int main()
{
printf("打印\n");
}
makefile 或 Makefile
app : main.o
cc -o app main.o
main.o : main.c
cc -c main.c
clean :
rm app main.o
说明:
app : mian.o
一种依赖关系的声明,生成程序app需要依赖 main.o 文件。
cc -o app main.o
一个终端命令, 执行该命令,gcc使用main.o文件生成app
main.o : main.c
同理,依赖关系声明,生成main.o需要main.c文件
cc -c main.c
使用gcc编译main.c文件,生成二进制文件main.o
clean :
清除命令,不依赖任何文件
rm app main.o
清除编译链接生成的所有文件,类似于xcode的command+shift+k
执行流程
$ make
在工作目录下执行make命令,make命令会按照makefile文件中的规则执行,首先是app:main.o,依赖关系声明生成app需要main.o文件,make命令检查main.o是否存在(是否最新)
- 如果存在(或最新),则执行表达式 cc -o app mian.c命令,生成app;
- 如果不存在(或不是最新),则去生成main.o
main.o生成,检查依赖,main.c是否存在(或最新)
- 如果存在(或最新),则执行表达式 cc -c mian.c命令,生成mian.o;
- 如果不存在,则报错
以上所有的命令都可以单独执行,如:
$ make main.o
$ make clean
2.简化使用
创建工作目录,包含如下文件:
- main.c
- person.c
- a.h
- b.h
1.文件内容,main.c同上,其他空文件即可。
创建makefile
app : main.o person.o other.o
cc -o app main.o person.o other.o
main.o : main.c
cc -c main.c a.h
person.o : person.c a.h b.h
cc -c person.c
other.o : person.c b.h
cc -c person.c -o other.o
clean :
rm app main.o person.o other.o
2.定义变量,代替目标文件,简化代码,如下:
objects = main.o person.o other.o
app : $(objects)
cc -o app $(objects)
main.o : main.c
cc -c main.c a.h
person.o : person.c a.h b.h
cc -c person.c
other.o : person.c b.h
cc -c person.c -o other.o
clean :
rm app $(objects)
3.使用makefile的自动推导机制,简化指令语句:
因为在编译过程中,哪些类型文件的编译需要哪些指令是固定的,所以makefile可以从依赖关系自动推导出后面要执行的语句
简化如下:
objects = main.o person.o
app : $(objects)
cc -o app $(objects)
main.o : main.c
person.o : person.c a.h b.h
clean :
rm app $(objects)
只有依赖声明下面没有任何语句,makefile才会自动推导,否则执行指定语句
注意:这里去掉了other.o,是因为,前面other.o依赖person.c 手动指定生成other.o,这里makefile只会生成和依赖文件相同名字的 .o 文件。
4.如果我们的文件不在一个目录,需要指定目录,只需要在makefile文件中第一行添加
VPATH = path1:path2:path3
makefile会自行按照路径顺序,依次查找文件。
5.最终版
VPATH = ./subfile:./otherPath
#这是一个注释
CC = gcc #设置编译器
objects = main.o person.o
app : $(objects)
$(CC) -o app $(objects) #使用设定的编译器编译
@echo "输出信息:编译完成"
main.o : main.c
person.o : person.c a.h b.h
.PHONY : clean #说明虚拟标号,表示clean不出现在依赖树中
clean :
rm app $(objects)
参考资料
makefile书写入门
比较全面的资料
makefile-1
makefile-2
makefile-3
makefile-4
makefile-5
makefile-6