使用隐含规则

如果要使用隐含规则生成你需要的目标,你所需要做的就是不要写出这个目标的规则。那么,make会试图去自动推导产生这个目标的规则和命令,如果 make可以自动推导生成这个目标的规则和命令,那么这个行为就是隐含规则的自动推导。当然,隐含规则是make事先约定好的一些东西。例如,我们有下面的一个Makefile:

  1. foo : foo.o bar.o
  2. cc o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)

我们可以注意到,这个Makefile中并没有写下如何生成 foo.obar.o 这两目标的规则和命令。因为make的“隐含规则”功能会自动为我们自动去推导这两个目标的依赖目标和生成命令。

make会在自己的“隐含规则”库中寻找可以用的规则,如果找到,那么就会使用。如果找不到,那么就会报错。在上面的那个例子中,make调用的隐含规则是,把 .o 的目标的依赖文件置成 .c ,并使用C的编译命令 cc –c $(CFLAGS) foo.c 来生成 foo.o 的目标。也就是说,我们完全没有必要写下下面的两条规则:

  1. foo.o : foo.c
  2. cc c foo.c $(CFLAGS)
  3. bar.o : bar.c
  4. cc c bar.c $(CFLAGS)

因为,这已经是“约定”好了的事了,make和我们约定好了用C编译器 cc 生成 .o 文件的规则,这就是隐含规则。

当然,如果我们为 .o 文件书写了自己的规则,那么make就不会自动推导并调用隐含规则,它会按照我们写好的规则忠实地执行。

还有,在make的“隐含规则库”中,每一条隐含规则都在库中有其顺序,越靠前的则是越被经常使用的,所以,这会导致我们有些时候即使我们显示地指定了目标依赖,make也不会管。如下面这条规则(没有命令):

  1. foo.o : foo.p

依赖文件 foo.p (Pascal程序的源文件)有可能变得没有意义。如果目录下存在了 foo.c 文件,那么我们的隐含规则一样会生效,并会通过 foo.c 调用C的编译器生成 foo.o 文件。因为,在隐含规则中,Pascal的规则出现在C的规则之后,所以,make找到可以生成 foo.o 的C的规则就不再寻找下一条规则了。如果你确实不希望任何隐含规则推导,那么,你就不要只写出“依赖规则”,而不写命令。