跟我一起写makefile

上传人:re****.1 文档编号:432877263 上传时间:2022-09-12 格式:DOCX 页数:5 大小:20.14KB
返回 下载 相关 举报
跟我一起写makefile_第1页
第1页 / 共5页
跟我一起写makefile_第2页
第2页 / 共5页
跟我一起写makefile_第3页
第3页 / 共5页
跟我一起写makefile_第4页
第4页 / 共5页
跟我一起写makefile_第5页
第5页 / 共5页
亲,该文档总共5页,全部预览完了,如果喜欢就下载吧!
资源描述

《跟我一起写makefile》由会员分享,可在线阅读,更多相关《跟我一起写makefile(5页珍藏版)》请在金锄头文库上搜索。

1、跟我一起写makefile(十三)定义模式规则 你可以使用模式规则来定义一个隐含规则。一个模式规则就好像一个一般的 规则,只是在规则中,目标的定义需要有%字符。%的意思是表示一个或多 个任意字符。在依赖目标中同样可以使用"%,只是依赖目标中的的取 值,取决于其目标。有一点需要注意的是, %的展开发生在变量和函数的展开之后,变量和函 数的展开发生在 make 载入 Makefile 时,而模式规则中的%则发生在运行时。1、模式规则介绍 模式规则中,至少在规则的目标定义中要包含%,否则,就是一般的规则。目标中的%定义表示对文件名的匹配, %表示长度任意的非空字符串。例如: %.c表示以;

2、.c结尾的文件名(文件名的长度至少为3),而s.%.c;则表示以s. 开头,.c结尾的文件名(文件名的长度至少为5)。如果%定义在目标中,那么,目标中的%的值决定了依赖目标中的% 的值,也就是说,目标中的模式的;%决定了依赖目标中%的样子。例如有一 个模式规则如下:%.o : %.c ; 其含义是,指出了怎么从所有的.c 文件生成相应的.o 文件的规则。如果要 生成的目标是a.o b.o,那么c 就是;a.c b.c。一旦依赖目标中的%模式被确定,那么, make 会被要求去匹配当前目录下 所有的文件名,一旦找到, make 就会规则下的命令,所以,在模式规则中,目 标可能会是多个的,如果有模

3、式匹配出多个目标, make 就会产生所有的模式目 标,此时, make 关心的是依赖的文件名和生成目标的命令这两件事。2、模式规则示例下面这个例子表示了,把所有的.c 文件都编译成.o 文件.%.o : %.c$(CC) -c $(CFLAGS) $(CPPFLAGS) $ -o $其中, $表示所有的目标的挨个值, $表示了所有依赖目标的挨个值。 这些奇怪的变量我们叫自动化变量",后面会详细讲述。下面的这个例子中有两个目标是模式的:%.tab.c %.tab.h: %.ybison -d $.y"执行,然后 生成vn.tab.c和vn.tab.h文件。(其中,vn表示一

4、个任意字符串)。如果我 们的执行程序foo依赖于文件parse.tab.o"和scan.o,并且文件scan.o依 赖于文件"parse.tab.h,如果parse.y文件被更新了,那么根据上述的规则, bison -d parse.y就会被执行一次,于是,parse.tab.o和scan.o的依赖文件就齐 了。(假设,parse.tab.o由parse.tab.c生成,和"scan.o由scan.c生成,而 foo由"parse.tab.o和scan.o链接生成,而且foo和其.o文件的依赖关系 也写好,那么,所有的目标都会得到满足)3、自动化变量在上

5、述的模式规则中,目标和依赖文件都是一系例的文件,那么我们如何书 写一个命令来完成从不同的依赖文件生成相应的目标?因为在每一次的对模式 规则的解析时,都会是不同的目标和依赖文件。自动化变量就是完成这个功能的。在前面,我们已经对自动化变量有所提涉, 相信你看到这里已对它有一个感性认识了。所谓自动化变量,就是这种变量会把 模式中所定义的一系列的文件自动地挨个取出,直至所有的符合模式的文件都取 完了。这种自动化变量只应出现在规则的命令中。下面是所有的自动化变量及其说明:$表示规则中的目标文件集。在模式规则中,如果有多个目标,那么, $ 就是匹配于目标中模式定义的集合。$%仅当目标是函数库文件中,表示规

6、则中的目标成员名。例如,如果一个目 标是foo.a(bar.o),那么,$%就是bar.o, $就是foo.a。如果目标不 是函数库文件(Unix下是.a, Windows下是.1 ib),那么,其值为空。$依赖目标中的第一个目标名字。如果依赖目标是以模式(即%")定 义的,那么$将是符合模式的一系列的文件集。注意,其是一个一个取出 来的。$?所有比目标新的依赖目标的集合。以空格分隔。$A所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的, 那个这个变量会去除重复的依赖目标,只保留一份。$+这个变量很像$A,也是所有依赖目标的集合。只是它不去除重复的依赖 目标。$*这个变

7、量表示目标模式中及其之前的部分。如果目标是dir/a.foo.b, 并且目标的模式是%.b,那么,“$*的值就是dir/a.foo。这个变量对于构造 有关联的文件名是比较有较。如果目标中没有模式的定义,那么$* &q uot;也就 不能被推导出,但是,如果目标文件的后缀是make所识别的,那么$*就是除 了后缀的那一部分。例如:如果目标是foo.c,因为.c是make所能识别的后缀 名,所以,;$*的值就是foo。这个特性是GNU make的,很有可能不兼容于 其它版本的make,所以,你应该尽量避免使用$*,除非是在隐含规则或是静 态模式中。如果目标中的后缀是make所不能识别的,那么$*就

8、是空值。当你希望只对更新过的依赖文件进行操作时, $?在显式规则中很有用,例 如,假设有一个函数库文件叫lib,其由其它几个object文件更新。那么把object 文件打包的比较有效率的Makefile规则是:lib : foo.o bar.o lose.o win.oar r lib $?在上述所列出来的自动量变量中。四个变量($、$、$%、$*)在扩展时 只会有一个文件,而另三个的值是一个文件列表。这七个自动化变量还可以取得文件的目录名或是在当前目录下的符合模式的文件名,只需要搭配上D或F 字样。这是GNU make中老版本的特性,在新版本中,我们使用函数dir或notdir 就可以做到

9、了。D的含义就是Directory,就是目录,F"的含义就是File, 就是文件。下面是对于上面的七个变量分别加上D 或是F的含义:$(D)表示$的目录部分(不以斜杠作为结尾),如果$值是dir/foo.o,那么 $(D)就是"dir,而如果$中没有包含斜杠的话,其值就是".(当 前目录)。$(F)表示$的文件部分,如果$值是dir/foo.o,那么$(F)就是foo.o, ;$(F)相当于函数$(notdir $)。$(*D)$(*F)和上面所述的同理,也是取文件的目录部分和文件部分。对于上面的那个例子, $(*D)返回dir,而$(*F)"返回foo

10、$(%D)$(%F)分别表示了 函数包文件成员的目 录部分和文件部分。 这对于形同 "archive(member)形式的目标中的member中包含了不同的目录很有用。 $(D)$(F)分别表示依赖文件的目录部分和文件部分。$(AD)$(AF)!分别表示所有依赖文件的目录部分和文件部分。(无相同的)$(+D)$(+F)分别表示所有依赖文件的目录部分和文件部分。(可以有相同的)$(?D)$(?F)分别表示被更新的依赖文件的目录部分和文件部分。最后想提醒一下的是,对于$,为了避免产生不必要的麻烦,我们最好给 $后面的那个特定字符都加上圆括号,比如, $(;)就要比$要好一些。还得要注意的

11、是,这些变量只使用在规则的命令中,而且一般都是显式规 则和静态模式规则(参见前面书写规则一章)。其在隐含规则中并没有意义。4、模式的匹配 一般来说,一个目标的模式有一个有前缀或是后缀的%,或是没有前后缀, 直接就是一个%。因为%代表一个或多个字符,所以在定义好了的模式中, 我们把所匹配的内容叫做茎,例如.c所匹配的文件test, c中test就是 茎。因为在目标和依赖目标中同时有%时,依赖目标的茎会传给目标,当做 目标中的茎。当一个模式匹配包含有斜杠(实际也不经常包含)的文件时,那么在进行模 式匹配时,目录部分会首先被移开,然后进行匹配,成功后,再把目录加回去。 在进行茎的传递时,我们需要知道

12、这个步骤。例如有一个模式e%t,文件 src/eat匹配于该模式,于是src/a就是其茎,如果这个模式定义在依赖目标中, 而被依赖于这个模式的目标中又有个模式c%r,那么,目标就是src/car。( 茎被传递)5、重载内建隐含规则 你可以重载内建的隐含规则(或是定义一个全新的),例如你可以重新构造 和内建隐含规则不同的命令,如:%.o : %.c$(CC) -c $(CPPFLAGS) $(CFLAGS) -D$(date) 你可以取消内建的隐含规则,只要不在后面写命令就行。如: %.o : %.s同样,你也可以重新定义一个全新的隐含规则,其在隐含规则中的位置取决 于你在哪里写下这个规则。朝前

13、的位置就靠前。六、老式风格的后缀规则 后缀规则是一个比较老式的定义隐含规则的方法。后缀规则会被模式规则逐 步地取代。因为模式规则更强更清晰。为了和老版本的 Makefile 兼容, GNU make 同样兼容于这些东西。后缀规则有两种方式:双后缀"和单后缀。双后缀 规则定义了一对后缀:目标文件的后缀和依赖目标(源文件)的后缀。如 .c.o 相当于%o : %c。单后缀规则只定义一个后缀,也就是源文件的后缀。女如.c相 当于% : %.c。后缀规则中所定义的后缀应该是make所认识的,如果一个后缀是make所 认识的,那么这个规则就是单后缀规则,而如果两个连在一起的后缀都被 make

14、所认识,那就是双后缀规则。例如:.c和.o都是make所知道。因而,如果你 定义了一个规则是co那么其就是双后缀规则,意义就是.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-builti

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 建筑/环境 > 建筑资料

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号