zoukankan      html  css  js  c++  java
  • 跟我学Makefile(七)

    定义模式规则

    使用模式规则来定义一个隐含规则。一个模式规则就好像一个一般的规则,只是在规则中,目标的定义需要有“%”字符。“%”的意思是表示一个或多个任意字符。在依赖目标中同样可以使用“%”,只是依赖目标中的“%”的取值,取决于其目标。

    有一点需要注意的是,%”的展开发生在变量和函数的展开之后变量和函数的展开发生在make 载入 Makefile ,而模式规则中的“%”则发生在运行时。

    模式规则介绍 :
    模式规则中,至少在规则的目标定义中要包含“%”,否则,就是一般的规则。目标中的“%”定义表示对文件名的匹配,“%”表示长度任意的非空字符串。例如:“%.c”表示以“.c”结尾的文件名(文件名的长度至少为 3),而“s.%.c”则表示以“s.”开头,“.c”结尾的
    文件名(文件名的长度至少为 5)。

    如果“%”定义在目标中,那么,目标中的“%”的值决定了依赖目标中的“%”的值,也就是说,目标中的模式的“%”决定了依赖目标中“%”的样子。

    %.o : %.c ; <command ......>

    其含义是,指出了怎么从所有的[.c]文件生成相应的[.o]文件的规则。如果要生成的目标是“a.o b.o”,那么“%c”就是“a.c b.c”。

    一旦依赖目标中的“%”模式被确定,那么, make 会被要求去匹配当前目录下所有的文件名,一旦找到, make 就会规则下的命令,所以,在模式规则中,目标可能会是多个的,如果有模式匹配出多个目标, make 就会产生所有的模式目标,此时,

    make 关心的是依赖的文件名和生成目标的命令这两件事。

    %.o : %.c                        //把所有的[.c]文件都编译成[.o]文件 
        $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

    $@”表示所有的目标的挨个值,“$<”表示了所有依赖目标的挨个值

    自动化变量说明

    $@
    表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,“$@”就是匹配于目标中模式定义的集合。
    $%
    仅当目 标是函数库 文件中,表 示规则中的 目标成员名 。例如,如 果一个目标 是“foo.a(bar.o)”,那么,“$%”就是“bar.o”,“$@”就是“foo.a”。如果目标不是函数库文件(Unix 下是[.a], Windows 下是[.lib]),那么,其值为空。
    $<
    依赖目标中的第一个目标名字。如果依赖目标是以模式(即“%”)定义的,那么“$<”将是符合模式的一系列的文件集。注意,其是一个一个取出来的。
    $?
    所有比目标新的依赖目标的集合。以空格分隔。
    $^
    所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
    $+
    这个变量很像“$^”,也是所有依赖目标的集合。只是它不去除重复的依赖目标。
    $*
    这个变量表示目标模式中“%”及其之前的部分。如果目标是“dir/a.foo.b”,并且目标的模式是“a.%.b”,那么,“$*”的值就是“dir/a.foo”。这个变量对于构造有关联的文件名是比较有较。如果目标中没有模式的定义,那么“$*”也就不能被推导出,但是,如果目标文件的后缀
    是 make 所识别的,那么“$
    *”就是除了后缀的那一部分。例如:如果目标是“foo.c”,因为“.c”是 make 所能识别的后缀名,所以,“$*”的值就是“foo”。这个特性是 GNU make 的,很有可能不兼容于其它版本的 make,所以,你应该尽量避免使用“$*”,除非是在隐含规则
    或是静态模式中。如果目标中的后缀是 make 所不能识别的,那么“$
    *”就是空值。

    四个变量($@$<$%$*)在扩展时只会有一个文件,而另三个的值是一个文件列表 。

    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” 。
    $(%D)
    $(%F)
    分别表示了函数包文件成员的目录部分和文件部分。这对于形同“archive(member)”形式的目标中的“member”中包含了不同的目录很有用。
    $(<D)
    $(<F)
    分别表示依赖文件的目录部分和文件部分。
    $(^D)
    $(^F)
    分别表示所有依赖文件的目录部分和文件部分。(无相同的)
    $(+D)
    $(+F)
    分别表示所有依赖文件的目录部分和文件部分。(可以有相同的)
    $(?D)
    $(?F)
    分别表示被更新的依赖文件的目录部分和文件部分。

  • 相关阅读:
    学习进度条第一周
    构建之法阅读笔记01
    软件工程个人作业01
    《构建之法》阅读笔记
    Day6:闭包函数、无参装饰器
    Day5:函数参数
    Day4:字符编码与文件处理
    Day3:数据类型(布尔值、集合)
    Day2:数据类型(列表、元组、字典)
    Day1:初识Python
  • 原文地址:https://www.cnblogs.com/Caden-liu8888/p/8377964.html
Copyright © 2011-2022 走看看