GNU Make 简介( 二 )


命令(COMMAND)是make 执行的动作,一个可以有多个命令,每个占一行 。

注意:每个命令行的起始字符必须为TAB 字符!

有依赖关系规则中的命令通常在依赖文件变化时负责产生target 文件,make 执行这些命令更新或产生target 。规则可以没有依赖关系,如包含target “clean”的规则 。

规则解释如何和何时重做该规则中的文件,make 根据依赖关系执行产生或更新目标;规则也说明如何和何时执行动作 。有的规则看起来很复杂,但都符合上述模式 。

1.4 make 工作原理

缺省make 从第一个target 开始(第一个非 "." 开始的target),这称作缺省目标 。在上述的makefile 中,缺省目标是更新执行程序"edit",将这个目标置于最前面 。当执行make 的时候,make 程序从当前目录读入makefile 开始处理第一个规则;在例子中,这个规则是重新链接"edit";在make 处理这个规则之前,必须处理"edit"所依赖的那些文件的规则,例子中是目标文件 。这些文件按照他们自己的规则处理:通过编译源文件来更新每个".o"文件;当依赖关系中的源文件或头文件比目标文件新,或目标文件不存在时,必须重新编译 。

其它的规则被处理是因为他们的target是目标的依赖,和目标没有依赖关系的规则不会被处理,除非指定make 处理(如make clean) 。在重新编译目标文件之前,make 会试图更新它的依赖:源文件和头文件 。例子中的makefile 对源文件和头文件未指定任何操作:".c"和".h"文件不是任何规则的目标 。确认所有的目标文件都是最新的之后,make 决定是否重新链接"edit":如果"edit"不存在,或者任何一个目标文件都比它新,则链接工作将进行 。

这样,如果我们改变insert.c 运行make,make 会编译这个文件来更新"insert.o",然后链接"edit";如果修改了"command.h"运行make,"kbd.o","command.o","files.o"会重新生成,链接"edit" 。

1.5 使用变量

在例子中,在规则"edit"中,目标文件被列出来两次:

edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o

这样的重复容易出错:假设工程中加入了一个新的目标文件,可能只将其加入了一个列表中;通过使用变量可以消除这种风险:变量允许一个预定义的字符串在多个地方被替换 。

在makefile 中,可以写这样一行来定义"object"变量:

objects = main.o kbd.o command.o display.o insert.o search.o files.o utils.o

于是在需要目标文件名列表的地方,使用$(object) 来代替变量的值 。以下是使用了变量以后的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 : main.c defs.h
cc -c main.c

kbd.o : kbd.c defs.h command.h
cc -c kbd.c

command.o : command.c defs.h command.h
cc -c command.c

display.o : display.c defs.h buffer.h
cc -c display.c

insert.o : insert.c defs.h buffer.h
cc -c insert.c

search.o : search.c defs.h buffer.h
cc -c search.c

files.o : files.c defs.h buffer.h command.h
cc -c files.c

utils.o : utils.c defs.h
cc -c utils.c

clean :
rm edit $(objects)
--------------------------------------------------------------------------------

1.6 简化命令

为每个文件写出编译命令不是必要的,因为make 可以自己来做;以".c"文件更新".o"文件有一个隐含的规则,使用"cc -c"命令 。Make 将利用"cc -c main.c -o main.o"来将main.c 编译为main.o,因此在生成目标文件的规则中,可以省略命令 。

推荐阅读