内核映像的形成 —— MakeFile预备知识(五)

2.1.5 隐含规则

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

foo : foo.o bar.o

cc –o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)

 

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

 

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

foo.o : foo.c

cc –c foo.c $(CFLAGS)

bar.o : bar.c

cc –c bar.c $(CFLAGS)

 

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

 

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

 

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

foo.o : foo.p

 

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

 

在隐含规则中的命令中,基本上都是使用了一些预先设置的变量。你可以在你的 makefile中改变这些变量的值,或是在make 的命令行中传入这些值,或是在你的环境变量中设置这些值,无论怎么样,只要设置了这些特定的变量,那么其就会对隐含规则起作用。当然,你也可以利用make 的“-R”或“--nobuiltin-variables”参数来取消你所定义的变量对隐含规则的作用。

 

例如,第一条隐含规则——编译C 程序的隐含规则的命令是

$(CC) c $(CFLAGS) $(CPPFLAGS)

 

Make 默认的编译命令是“ cc”,如果你把变量“$(CC)”重定义成“gcc”,把变量“$(CFLAGS)”重定义成“-g”,那么,隐含规则中的命令全部会以“gcc c –g $(CPPFLAGS)”的样子来执行了。

 

我们可以把隐含规则中使用的变量分成两种:一种是命令相关的,如“CC”;一种是参数相的关,如“CFLAGS”。

你可能感兴趣的:(c,gcc,pascal,makefile,编译器)