老式风格的“后缀规则”

后缀规则是一个比较老式的定义隐含规则的方法。后缀规则会被模式规则逐步地取代。因为模式规则更强更清晰。为了和老版本的Makefile兼容,GNU make同样兼容于这些东西。后缀规则有两种方式:“双后缀”和“单后缀”。

双后缀规则定义了一对后缀:目标文件的后缀和依赖目标(源文件)的后缀。如 .c.o 相当于 %o : %c 。单后缀规则只定义一个后缀,也就是源文件的后缀。如 .c 相当于 % : %.c

后缀规则中所定义的后缀应该是make所认识的,如果一个后缀是make所认识的,那么这个规则就是单后缀规则,而如果两个连在一起的后缀都被make所认识,那就是双后缀规则。例如: .c.o 都是make所知道。因而,如果你定义了一个规则是 .c.o 那么其就是双后缀规则,意义就是 .c 是源文件的后缀, .o是目标文件的后缀。如下示例:

  1. .c.o:
  2. $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

后缀规则不允许任何的依赖文件,如果有依赖文件的话,那就不是后缀规则,那些后缀统统被认为是文件名,如:

  1. .c.o: foo.h
  2. $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

这个例子,就是说,文件 .c.o 依赖于文件 foo.h ,而不是我们想要的这样:

  1. %.o: %.c foo.h
  2. $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

后缀规则中,如果没有命令,那是毫无意义的。因为他也不会移去内建的隐含规则。

而要让make知道一些特定的后缀,我们可以使用伪目标 .SUFFIXES 来定义或是删除,如:

  1. .SUFFIXES: .hack .win

把后缀 .hack.win 加入后缀列表中的末尾。

  1. .SUFFIXES: # 删除默认的后缀
  2. .SUFFIXES: .c .o .h # 定义自己的后缀

先清除默认后缀,后定义自己的后缀列表。

make的参数 -r-no-builtin-rules 也会使用得默认的后缀列表为空。而变量SUFFIXE 被用来定义默认的后缀列表,你可以用 .SUFFIXES 来改变后缀列表,但请不要改变变量 SUFFIXE 的值。