在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。
target ... : prerequisites ...
command
...
...
例如:
edit: edit1.o edit2.o/
edit3.o edit4.o
cc -o edit edit1.o edit2.o/
edit3.o edit4.o
edit1.o : edit1.h edit1.cpp
cc -c edit1.cpp
edit2.o : edit2.h edit2.cpp
cc -c edit1.cpp
edit3.o : edit3.h edit3.cpp
cc -c edit1.cpp
clean:
rm edit edit1.o edit2.o edit3.o edit4.o
说明:
(1)反斜杠(/)是换行符的意思。
(2)cc -o 等价于gcc -o: 表示将输出输入到指定文件,表示产生目标文件
(3)cc -c 等价于gcc -c: 表示编译、汇编 但不连接
(4)rm 表示删除指定文件的意思
1.1makefile 是如何工作的
(1)执行make命令第一步,在当前目录下,查找“makefile”文件;
(2)如果找到“makefile”文件,在该文件中找到第一个目标文件“target”(就是例子中的“edit”);
(3)如果目标文件不存在,又或者目标文件依赖的.o 文件比目标文件新,那么执行后面的定义来重新生成目标文件;
(4)如果目标文件所依赖的.o 文件也不存在,则继续根据规则生成.o文件。
(5)一旦生成.o文件,就开始生成目标文件。
注意:
一旦我们修改了一个.c或者.cpp文件,那么就会导致一个.o文件重新生成,.o文件比目标文件新,就会生成更新的目标文件。
1.2makefile中使用变量
可以定义变量
XXX = YYYYY;那么XXX将代替YYYYY;
假设定义:
OBJECT = edit1.o edit2.o/
edit3.o edit4.o
那么重新写:
edit: $(OBJECT)
cc -o edit $(OBJECT)
edit1.o : edit1.h edit1.cpp
cc -c edit1.cpp
edit2.o : edit2.h edit2.cpp
cc -c edit1.cpp
edit3.o : edit3.h edit3.cpp
cc -c edit1.cpp
clean:
rm edit $( OBJECT )
隐晦规则:只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件;于是: cc -c whatever.c 也会被推导出来;
上述代码简化为:
OBJECT = edit1.o edit2.o edit3.o edit4.o
edit: $(OBJECT)
cc -o edit $(OBJECT)
edit1.o : edit1.h
edit2.o : edit2.h
edit3.o : edit3.h
.PHONY: clean
clean:
rm edit $( OBJECT )
说明:.PHONY 用于说明 chean 是一个“伪目标文件”;
1.4清空目标文件规则
每一个makefile中都应该写一个清空目标文件(.o文件和执行文件)规则,这不仅有利于重新编译,还有利于保持文件的清洁。
二 Makefile文件详细说明
2.1makefile里面有什么
五种东西:显示规则、隐式规则、变量定义、文件指示、注释
重点解释:
注释:#打头表示注释,如果需要在makefile中使用#,可以使用转义字符,例如'/#'。
文件指示:包含三个部分:(1)在一个makefile中引用另一个makefile,类似于“include”。
(2)
(3)
2.2规则中使用通配符
make支持三种通配符:‘ * ’、‘ ?’、‘ [...]’;
vpath % inlude2
2.4多目标
2.5静态模式
静态模式语法:
<targets...>:<targets-pattern>:<PreReq-pattern..>
<targets..> 表示一系列的目标文件集合;
<targets-pattern> 表示目标集模式;
<PreReq-pattern..> 表示目标的依赖模式;
例如:
objects = foo.o bar.o
all:$(objects)
$(objects):%.o:%.c
$(CC) -c $(CFLAGS) $< -o $@
注释:
命令中"$<"和"$@"都是自动化变量,
“$<”表示所有的目标依赖集,"$@"表示所有的目标集
2.6自动生成依赖性
大多数C/C++编译器都支持一个“-M”的选项,即:自动寻找源文件所依赖的头文件,并生成一个依赖关系。
edit1.o : edit1.h edit1.cpp
cc -c edit1.cpp
edit2.o : edit2.h edit2.cpp
cc -c edit1.cpp
edit3.o : edit3.h edit3.cpp
cc -c edit1.cpp
rm edit $( OBJECT )