makefile结构
- 显式规则 ==》 生成语句什么的直接写出来
- 隐式规则 ==》 自动推导(并不建议,毕竟不完全可控)
- 变量定义 ==》 使用见下文
- 文件引用 ==》 1. 在一个makefile中使用另一个makefile;2. 根据某些情况指定makefile中的有效部分;3. 定义一个多行命令
- 注释 ==》 以#开头,如果需要在makefile中使用#字符,可以:#
最简单的makefile
hello: hello.o
hello.o: hello.c
gcc -c hello.c -o hello.o
#下面的用于清理文件
.PHONY:clean #.PHONY意思表示clean是一个“伪目标”。也即是无论clean是否最新,一定执行它。
clean:
-rm -rf *.o # rm前面加上-的意思是,忽略错误文件
执行
命令:make
- make会在当前目录下找“makefile”文件或“MakeFile”文件
- 找文件中的第一个目标文件【在上面的例子中也就是hello】,将这个目标文件作为最终的目标文件
- 如果这个最终的目标文件不存在或者依赖的.o文件的文件修改时间比目标文件的新,就会重新使用命令来生成这个目标文件
- 如果依赖的.o不存在,会先生成这个.o文件
make会一层层地去找文件的依赖关系,直到编译出第一个目标文件;如果出现错误【找不到依赖文件的这种错误】,那么make就会直接退出,并且报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。make只管文件的依赖性。
变量定义使用
比如:
OBJS = main.o a.o b.o
main:$(OBJS)
%.o:%.c
gcc - c $^ -o $@
clean:
-rm -rf $(OBJS)
- $^ 代表所有的依赖文件
- $@ 代表所有的目标文件
- $< 代表第一个依赖文件
- %.o:%.c 表示所有的.o文件依赖的.c文件【cpp文件就改成%.o:%.cpp】
makefile使用基本规则
在应用时候,定下的规则一般这样:
- 如果这个工程没有编译过,那么我们的所有c文件都要编译并被链接。
- 如果这个工程的某几个c文件被修改,那么我们只编译被修改的c文件,并链接目标程序。
- 如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的c文件,并链接目标程序。