第十一部分 隐含规则(四)

发布时间:2024年01月18日

目录

一、老式风格的"后缀规则"

二、隐含规则搜索算法


一、老式风格的"后缀规则"

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

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

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

.c.o:

$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

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

.c.o: foo.h

$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

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

%.o: %.c foo.h

$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<

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

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

.SUFFIXES: .hack .win

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

.SUFFIXES: # 删除默认的后缀

.SUFFIXES: .c .o .h # 定义自己的后缀

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

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

二、隐含规则搜索算法

????????比如我们有一个目标叫 T。下面是搜索目标 T 的规则的算法。请注意,在下面,我们没 有提到后缀规则,原因是,所有的后缀规则在 Makefile 被载入内存时,会被转换成模式规 则。如果目标是"archive(member)"的函数库文件模式,那么这个算法会被运行两次,第一 次是找目标 T,如果没有找到的话,那么进入第二次,第二次会把"member"当作 T 来搜索。

???????? 1、把 T 的目录部分分离出来。叫 D,而剩余部分叫 N。(如:如果 T 是"src/foo.o",那 么,D 就是"src/",N 就是"foo.o")

????????2、创建所有匹配于 T 或是 N 的模式规则列表。

????????3、如果在模式规则列表中有匹配所有文件的模式,如"%",那么从列表中移除其它的模 式。

????????4、移除列表中没有命令的规则。

????????5、对于第一个在列表中的模式规则:

1)推导其"茎"S,S 应该是 T 或是 N 匹配于模式中"%"非空的部分。

2)计算依赖文件。把依赖文件中的"%"都替换成"茎"S。如果目标模式中没有包含 斜框字符,而把 D 加在第一个依赖文件的开头。

3)测试是否所有的依赖文件都存在或是理当存在。(如果有一个文件被定义成另外 一个规则的目标文件,或者是一个显式规则的依赖文件,那么这个文件就叫"理当存在")

4)如果所有的依赖文件存在或是理当存在,或是就没有依赖文件。那么这条规则 将被采用,退出该算法。

????????6、如果经过第 5 步,没有模式规则被找到,那么就做更进一步的搜索。对于存在于列 表中的第一个模式规则:

1)如果规则是终止规则,那就忽略它,继续下一条模式规则。

2)计算依赖文件。(同第 5 步)

3)测试所有的依赖文件是否存在或是理当存在。

4)对于不存在的依赖文件,递归调用这个算法查找他是否可以被隐含规则找到。

5)如果所有的依赖文件存在或是理当存在,或是就根本没有依赖文件。那么这条 规则被采用,退出该算法。

????????7、如果没有隐含规则可以使用,查看".DEFAULT"规则,如果有,采用,把".DEFAULT" 的命令给 T 使用。

???????? 一旦规则被找到,就会执行其相当的命令,而此时,我们的自动化变量的值才会生成。

文章来源:https://blog.csdn.net/qq_42700289/article/details/135590324
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。