下载

0下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 新妈咪和小宝贝的生活用品.doc

新妈咪和小宝贝的生活用品.doc.doc

新妈咪和小宝贝的生活用品.doc

shen伟深
2018-10-11 0人阅读 举报 0 0 0 暂无简介

简介:本文档为《新妈咪和小宝贝的生活用品.docdoc》,可适用于综合领域

新妈咪和小宝贝的生活用品doc跟我一起写makefile(十三)定义模式规则你可以使用模式规则来定义一个隐含规则。一个模式规则就好像一个一般的规则只是在规则中目标的定义需要有""字符。""的意思是表示一个或多个任意字符。在依赖目标中同样可以使用"只是依赖目标中的""的取值取决于其目标。有一点需要注意的是""的展开发生在变量和函数的展开之后变量和函数的展开发生在make载入Makefile时而模式规则中的""则发生在运行时。、模式规则介绍模式规则中至少在规则的目标定义中要包含""否则就是一般的规则。目标中的""定义表示对文件名的匹配""表示长度任意的非空字符串。例如:"c"表示以"c"结尾的文件名(文件名的长度至少为)而"sc"则表示以"s"开头"c"结尾的文件名(文件名的长度至少为)。如果""定义在目标中那么目标中的""的值决定了依赖目标中的""的值也就是说目标中的模式的""决定了依赖目标中""的样子。例如有一个模式规则如下:o:c<command>其含义是指出了怎么从所有的c文件生成相应的o文件的规则。如果要生成的目标是"aobo"那么"c"就是"acbc"。一旦依赖目标中的""模式被确定那么make会被要求去匹配当前目录下所有的文件名一旦找到make就会规则下的命令所以在模式规则中目标可能会是多个的如果有模式匹配出多个目标make就会产生所有的模式目标此时make关心的是依赖的文件名和生成目标的命令这两件事。、模式规则示例下面这个例子表示了,把所有的c文件都编译成o文件o:c$(CC)c$(CFLAGS)$(CPPFLAGS)$<o$其中"$"表示所有的目标的挨个值"$<"表示了所有依赖目标的挨个值。这些奇怪的变量我们叫"自动化变量后面会详细讲述。下面的这个例子中有两个目标是模式的:tabctabh:ybisond$<这条规则告诉make把所有的y文件都以"bisond<n>y执行然后生成"<n>tabc"和"<n>tabh"文件。(其中"<n>"表示一个任意字符串)。如果我们的执行程序"foo"依赖于文件"parsetabo和"scano"并且文件"scano"依赖于文件parsetabh"如果"parsey"文件被更新了那么根据上述的规则"bisondparsey"就会被执行一次于是"parsetabo"和"scano"的依赖文件就齐了。(假设"parsetabo"由"parsetabc"生成和scano"由"scanc"生成而"foo"由parsetabo"和"scano"链接生成而且foo和其o文件的依赖关系也写好那么所有的目标都会得到满足)、自动化变量在上述的模式规则中目标和依赖文件都是一系例的文件那么我们如何书写一个命令来完成从不同的依赖文件生成相应的目标,因为在每一次的对模式规则的解析时都会是不同的目标和依赖文件。自动化变量就是完成这个功能的。在前面我们已经对自动化变量有所提涉相信你看到这里已对它有一个感性认识了。所谓自动化变量就是这种变量会把模式中所定义的一系列的文件自动地挨个取出直至所有的符合模式的文件都取完了。这种自动化变量只应出现在规则的命令中。下面是所有的自动化变量及其说明:$表示规则中的目标文件集。在模式规则中如果有多个目标那么"$"就是匹配于目标中模式定义的集合。$仅当目标是函数库文件中表示规则中的目标成员名。例如如果一个目标是"fooa(baro)"那么"$"就是"baro""$"就是"fooa"。如果目标不是函数库文件(Unix下是aWindows下是lib)那么其值为空。$<依赖目标中的第一个目标名字。如果依赖目标是以模式(即")定义的那么"$<"将是符合模式的一系列的文件集。注意其是一个一个取出来的。$所有比目标新的依赖目标的集合。以空格分隔。$^所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的那个这个变量会去除重复的依赖目标只保留一份。$这个变量很像"$^"也是所有依赖目标的集合。只是它不去除重复的依赖目标。$*这个变量表示目标模式中""及其之前的部分。如果目标是"dirafoob"并且目标的模式是"ab"那么"$*"的值就是"dirafoo"。这个变量对于构造有关联的文件名是比较有较。如果目标中没有模式的定义那么"$*也就不能被推导出但是如果目标文件的后缀是make所识别的那么"$*"就是除了后缀的那一部分。例如:如果目标是"fooc"因为"c"是make所能识别的后缀名所以"$*"的值就是"foo"。这个特性是GNUmake的很有可能不兼容于其它版本的make所以你应该尽量避免使用"$*"除非是在隐含规则或是静态模式中。如果目标中的后缀是make所不能识别的那么"$*"就是空值。当你希望只对更新过的依赖文件进行操作时"$"在显式规则中很有用例如假设有一个函数库文件叫"lib"其由其它几个object文件更新。那么把object文件打包的比较有效率的Makefile规则是:lib:fooobaroloseowinoarrlib$在上述所列出来的自动量变量中。四个变量($、$<、$、$*)在扩展时只会有一个文件而另三个的值是一个文件列表。这七个自动化变量还可以取得文件的目录名或是在当前目录下的符合模式的文件名只需要搭配上"D"或"F"字样。这是GNUmake中老版本的特性在新版本中我们使用函数"dir"或"notdir"就可以做到了。"D"的含义就是Directory就是目录"F的含义就是File就是文件。是"F"的含义:下面是对于上面的七个变量分别加上"D"或$(D)表示"$"的目录部分(不以斜杠作为结尾)如果"$"值是"dirfooo"那么"$(D)"就是dir"而如果"$"中没有包含斜杠的话其值就是"(当前目录)。$(F)表示"$"的文件部分如果"$"值是"dirfooo"那么"$(F)"就是"fooo""$(F)"相当于函数"$(notdir$)"。"$(*D)""$(*F)"和上面所述的同理也是取文件的目录部分和文件部分。对于上面的那个例子"$(*D)"返回"dir"而"$(*F)返回"foo""$(D)""$(F)"分别表示了函数包文件成员的目录部分和文件部分。这对于形同archive(member)"形式的目标中的"member"中包含了不同的目录很有用。"$(<D)""$(<F)"分别表示依赖文件的目录部分和文件部分。"$(^D)""$(^F)"分别表示所有依赖文件的目录部分和文件部分。(无相同的)"$(D)""$(F)"分别表示所有依赖文件的目录部分和文件部分。(可以有相同的)"$(D)""$(F)"分别表示被更新的依赖文件的目录部分和文件部分。最后想提醒一下的是对于"$<"为了避免产生不必要的麻烦我们最好给$后面的那个特定字符都加上圆括号比如"$(<)"就要比"$<"要好一些。还得要注意的是这些变量只使用在规则的命令中而且一般都是"显式规则"和"静态模式规则"(参见前面"书写规则"一章)。其在隐含规则中并没有意义。、模式的匹配一般来说一个目标的模式有一个有前缀或是后缀的""或是没有前后缀直接就是一个""。因为""代表一个或多个字符所以在定义好了的模式中我们把""所匹配的内容叫做"茎"例如"c"所匹配的文件"testc"中"test"就是"茎"。因为在目标和依赖目标中同时有""时依赖目标的"茎"会传给目标当做目标中的"茎"。当一个模式匹配包含有斜杠(实际也不经常包含)的文件时那么在进行模式匹配时目录部分会首先被移开然后进行匹配成功后再把目录加回去。在进行"茎"的传递时我们需要知道这个步骤。例如有一个模式"et"文件"srceat"匹配于该模式于是"srca"就是其"茎"如果这个模式定义在依赖目标中而被依赖于这个模式的目标中又有个模式"cr"那么目标就是"srccar"。("茎"被传递)、重载内建隐含规则你可以重载内建的隐含规则(或是定义一个全新的)例如你可以重新构造和内建隐含规则不同的命令如:o:c$(CC)c$(CPPFLAGS)$(CFLAGS)D$(date)你可以取消内建的隐含规则只要不在后面写命令就行。如:o:s同样你也可以重新定义一个全新的隐含规则其在隐含规则中的位置取决于你在哪里写下这个规则。朝前的位置就靠前。六、老式风格的"后缀规则"后缀规则是一个比较老式的定义隐含规则的方法。后缀规则会被模式规则逐步地取代。因为模式规则更强更清晰。为了和老版本的Makefile兼容GNUmake同样兼容于这些东西。后缀规则有两种方式:"双后缀和"单后缀"。双后缀规则定义了一对后缀:目标文件的后缀和依赖目标(源文件)的后缀。如"co"相当于"o:c"。单后缀规则只定义一个后缀也就是源文件的后缀。如"c"相当于":c"。后缀规则中所定义的后缀应该是make所认识的如果一个后缀是make所认识的那么这个规则就是单后缀规则而如果两个连在一起的后缀都被make所认识那就是双后缀规则。例如:"c"和"o"都是make所知道。因而如果你定义了一个规则是"co"那么其就是双后缀规则意义就是"c"是源文件的后缀"o"是目标文件的后缀。如下示例:co:$(CC)c$(CFLAGS)$(CPPFLAGS)o$$<后缀规则不允许任何的依赖文件如果有依赖文件的话那就不是后缀规则那些后缀统统被认为是文件名如:co:fooh$(CC)c$(CFLAGS)$(CPPFLAGS)o$$<这个例子就是说文件"co"依赖于文件"fooh"而不是我们想要的这样:o:cfooh$(CC)c$(CFLAGS)$(CPPFLAGS)o$$<后缀规则中如果没有命令那是毫无意义的。因为他也不会移去内建的隐含规则。而要让make知道一些特定的后缀我们可以使用伪目标"SUFFIXES来定义或是删除如:SUFFIXES:hackwin把后缀hack和win加入后缀列表中的末尾。SUFFIXES:#删除默认的后缀SUFFIXES:coh#定义自己的后缀先清楚默认后缀后定义自己的后缀列表。make的参数"r"或"nobuiltinrules"也会使用得默认的后缀列表为空。而变量"SUFFIXE"被用来定义默认的后缀列表你可以用"SUFFIXES"来改变后缀列表但请不要改变变量"SUFFIXE"的值。七、隐含规则搜索算法比如我们有一个目标叫T。下面是搜索目标T的规则的算法。请注意在下面我们没有提到后缀规则原因是所有的后缀规则在Makefile被载入内存时会被转换成模式规则。如果目标是"archive(member)"的函数库文件模式那么这个算法会被运行两次第一次是找目标T如果没有找到的话那么进入第二次第二次会把"member"当作T来搜索。、把T的目录部分分离出来。叫D而剩余部分叫N。(如:如果T是"srcfooo"那么D就是"src"N就是"fooo)、创建所有匹配于T或是N的模式规则列表。、如果在模式规则列表中有匹配所有文件的模式如""那么从列表中移除其它的模式。、移除列表中没有命令的规则。、对于第一个在列表中的模式规则:)推导其"茎"SS应该是T或是N匹配于模式中"非空的部分。)计算依赖文件。把依赖文件中的""都替换成"茎"S。如果目标模式中没有包含斜框字符而把D加在第一个依赖文件的开头。)测试是否所有的依赖文件都存在或是理当存在。(如果有一个文件被定义成另外一个规则的目标文件或者是一个显式规则的依赖文件那么这个文件就叫"理当存在"))如果所有的依赖文件存在或是理当存在或是就没有依赖文件。那么这条规则将被采用退出该算法。、如果经过第步没有模式规则被找到那么就做更进一步的搜索。对于存在于列表中的第一个模式规则:)如果规则是终止规则那就忽略它继续下一条模式规则。)计算依赖文件。(同第步))测试所有的依赖文件是否存在或是理当存在。)对于不存在的依赖文件递归调用这个算法查找他是否可以被隐含规则找到。)如果所有的依赖文件存在或是理当存在或是就根本没有依赖文件。那么这条规则被采用退出该算法。、如果没有隐含规则可以使用查看"DEFAULT"规则如果有采用把"DEFAULT"的命令给T使用。一旦规则被找到就会执行其相当的命令而此时我们的自动化变量的值才会生成。

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

评分:

/9

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利