1.简介
1.1 makefile说明
- 编译时,编译器需要的是语法的正确,函数与变量的声明的正确。
- 链接时,主要是链接函数和全局变量。
链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),
在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标
文件名,这对于编译很不方便。所以,我们要给中间目标文件打个包,在 Windows 下这种包叫“库文
件”(Library File),也就是 .lib 文件,在 UNIX 下,是 Archive File,也就是 .a 文件。
Makefile规则:
- 如果这个工程没有编译过,那么我们的所有 c 文件都要编译并被链接。
- 如果这个工程的某几个 c 文件被修改,那么我们只编译被修改的 c 文件,并链接目标程序。
- 如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的 c 文件,并链接目标程
序。
make 会比较 targets 文
件和 prerequisites 文件的修改日期,如果 prerequisites 文件的日期要比 targets 文件的日期要新,或者
target 不存在的话,那么,make 就会执行后续定义的命令。
Makefile工作过程:make 会在当前目录下找名字叫“Makefile”或“makefile”的文件。如果找不到,它会找文件中的第一个目标文件(target).整个 make 的依赖性,make 会一层又一层地去找文件的依赖关系,直到最终编译出第一个目
标文件。
Makefile 里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。在 Makefile 中的命令,必须要以 Tab 键开始。
1.2.makefile 中使用变量
objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h
.PHONY : clean
clean :
-rm edit $(objects)
.PHONY
表示 clean 是一个“伪目标”。而在 rm 命令前面加了一个小减号的意思就是,也
许某些文件出现问题,但不要管,继续做后面的事。当然,clean 的规则不要放在文件的开头,不然,这就会变成 make 的默认目标,相信谁也不愿意这样。不成文的规矩是——“clean 从来都是放在文件的最后”。
1.3 引用其它的 Makefile
include包含其他makefile:
include <filename>
在 include 前面可以有一些空字符,但是绝不能是 Tab 键开始。如a.mk 、b.mk 、c.mk ,还有一个文件叫 foo.make
,以及一个变量 $(bar) ,其包含了 e.mk 和 f.mk:include foo.make *.mk $(bar)
如果你想让 make 不理那些无法读取的文件,而继续执行,你可以在include 前加一个减号“-”。如:-include <filename>
,其表示,无论 include 过程中出现什么错误,都不要报错继续执行。和其它版本 make 兼容的相关命令是 sinclude,其作用和这一个是一样的。
1.4 make 的工作方式
GNU 的 make 工作时的执行步骤如下:
- 读入所有的 Makefile。
- 读入被 include 的其它 Makefile。
- 初始化文件中的变量。
- 推导隐晦规则,并分析所有规则。
- 为所有的目标文件创建依赖关系链。
- 根据依赖关系,决定哪些目标要重新生成。
- 执行生成命令。
1-5 步为第一个阶段,6-7 为第二个阶段。
第一个阶段中,如果定义的变量被使用了,那么,make 会把其展开在使用的位置。但 make 并不会完全马上展开,make 使用的是拖延战术,如果变量出现在依赖关系的规则中,那么仅当这条依赖被决定要使用了,变量才会在其内部展开。
2.书写规则
targets : prerequisites ; command
command
...
如果命令太长,你可以使用反斜杠(\
)作为换行符。