二 后缀规则
2.1 双后缀规则
在前面的makefile例中有许多重复内容,例如,生成hello和hello1的命令类似,生成hello.o和hello1.o的命令也类似,除了编译或链接的文件不一样外,其它均相同,这时,我们就可以使用后缀规则。首先看一个双后缀的例子:
图 4 使用双后缀规则的makefile例
后缀规则使用特殊的目标名“.SUFFIXES”。
第一行中.SUFFIXES的依赖表为空,用来清除原有的后缀规则,因为.SUFFIXES可以在makefile中多次使用,每一次都将新的后缀规则加入以前的后缀规则中。
第二行中指定后缀规则为“.c .o”,即表示将所有的.c文件转换为.o文件。
第三行指定将.c文件转换成.o文件的方法。$(CC)为make的预定义宏,其默认值为cc,$<为特殊的宏,代替当前的源文件,即所有要编译的.c文件。
第六行指定目标hello和hello1的生成方法。$@为特殊的宏,代替当前的目标名,即hello和hello1,$@.o即为hello.o和hello1.o。
上例介绍的是双后缀规则,即它包含两个后缀,如.c.o,用来把一个C源文件编译为目标文件。双后缀规则描述如何由第一个后缀类型的文件生成第二个后缀类型的文件,例如:.c.o规则描述如何由.c文件生成.o文件。
2.2 单后缀规则
单后缀规则描述了怎样由指定后缀的文件生成由它基名为名字的文件。例如使用单后缀规则.c,可以由hello.c和hello1.c生成hello和hello1文件。例如将前面的makefile改为:
图 5 使用单后缀规则的makefile例
由于.c后缀规则为make标准后缀规则,make为其指定了相应的命令行,所以在makefile中可以不用再指定其目标生成的具体命令行。
下表是make提供的标准后缀规则。
表 1 make标准后缀规则
后缀规则 命令行
.c $(LINK.c) –o $@ $< $(LDLIBS)
.c.ln $(LINK.c) $(POUTPUT OPTPUT OPTION) –i $<
.c.o $(COMPILE.c) $(OUTPUT OPTION) $<
.c.a $(COMPILE.c) –o $% $<
$(AR) $(ARFLAGS) $@ $%
$(RM) $%
三 特殊目标
在后缀规则中使用了特殊目标.SUFFIXES,用来指定新增的后缀规则。make还提供了几个特殊目标来设置make的行为,下面为一些特殊的目标:
.IGNORE
make在执行命令行时,如果返回的是错误码,make的缺省动作是停止并退出。增加该目标后,make将忽略命令行返回的错误码,并继续执行后续的操作。
.SILENT
前面已经介绍过,make在执行命令行时会回显命令行内容,在命令行前增加“@”字符将抑制该命令行的回显。
如果增加该目标,所有的命令行不再回显,相当于在每个命令行前均增加了“@”字符。
.PRECIOUS
当收到一个信号或从shell命令返回非零的错误码时,make删除它所有已建立的文件。但有些文件即使出了错误,用户也不想让make删除,这些文件可以作为.PRECIOUS目标的参数。它可以在一个makefile中出现多次,每一次都累积文件列表。
.SUFFIXES
它为makefile指定新的后缀规则,新的后缀规则作为.SUFFIXES的依赖表给出。.SUFFIXES可以在一个makefile中多次使用,每一次都将新的后缀规则加入以前的后缀规则中,如果.SUFFIXES的依赖表为空,则设置后缀规则表为空。
四 特殊的宏
为简单使用规则,make提供了几个特殊的宏:
$@
整个当前目标名的值可以由宏“$@”来代替。
$<
当前的源文件由“$<”来代替。例如,在前面的例子中用到了$(CC) –c $<,其中的“$<”是所有要编译的.c文件。宏“$<”仅在后缀规则或.DEFAULT中有效。
$*
当前目标的基名由宏“$*”来代替。例如目标的名字是hello.o,则基名就是除去了后缀.o的hello。
以上介绍的特殊宏使用了make自身的规则,用户不可以改变。下表介绍了C中预定义的宏。
用途 宏 默认值
库文档汇编命令 AR ar
ARFLAGS rv
AS as
ASFLAGS
COMPILE.s $(AS) $(ASFLAGS) $(TARGET ARCH)
C编译器命令 CC cc
CFLAGS
CPPFLAGS
COMPILE.c $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET ARCH) –c
LINK.c $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET ARCH)
链接编辑器命令 LD ld
LDFLAGS
rm命令 RM rm
后缀列表 SUFFIXES .o .c .c~ .s .s~ .S .S~ .ln .f .f~ .F .F~ .l .mod .mod~ .sym
.def .def~ .p .p~ .r .r~ .y .y~ .h .h~ .sh .sh~ .cps .cps~
五 makefile的应用
当调用make时,它在当前目录下搜索文件名是“makefile”或“Makefile”的文件,并执行。
如果不想使用上述缺省文件,可以使用命令行中的“-f”来指定文件,如将编写的makefile命名为mklib,则指定为“make –f mklib”。
