定义模式规则

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

有一点需要注意的是,%”的展开发生在变量和函数的展开之后变量和函数的展开发生在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)”
分别表示被更新的依赖文件的目录部分和文件部分。

跟我学Makefile(七)的更多相关文章

  1. Mina、Netty、Twisted一起学(七):发布/订阅(Publish/Subscribe)

    消息传递有很多种方式,请求/响应(Request/Reply)是最常用的.在前面的博文的例子中,很多都是采用请求/响应的方式,当服务器接收到消息后,会立即write回写一条消息到客户端.HTTP协议也 ...

  2. 从头开始学JavaScript (七)——函数

    原文:从头开始学JavaScript (七)--函数 一.return 函数在执行完return之后停止并立即退出. return返回值:与return: 如下两个例子: function sum(n ...

  3. 跟我学Makefile(三)

    紧接着跟我学Makefile(二)继续学习:变量高级用法 (1)变量值的替换 :替换变量中的共有的部分,其格式是“$(var:a=b)”或是“${var:a=b}”,把变量“var”中所有以“a”字串 ...

  4. Mina、Netty、Twisted一起学(七):公布/订阅(Publish/Subscribe)

    消息传递有非常多种方式.请求/响应(Request/Reply)是最经常使用的.在前面的博文的样例中.非常多都是採用请求/响应的方式.当server接收到消息后,会马上write回写一条消息到clie ...

  5. 一起学makefile

    Unix.Linux必学知识哈哈,网上看到一哥们写得挺好挺详细的,直接复制地址就分享哈哈哈. 跟我一起写 Makefile(一) 概述 跟我一起写 Makefile(二) make是如何工作的 跟我一 ...

  6. 跟我一起学Makefile

    概述 什么是makefile?或许很多Winodws程序员都不知道这个东西,因为那些Windows IDE都为你做了这个工作,但我觉得要做一个好的和professional的程序员,makefile还 ...

  7. 跟我一起写Makefile(七)

    make 的运行—————— 一般来说,最简单的就是直接在命令行下输入make命令,make命令会找当前目录的makefile来执行,一切都是自动的.但也有时你也许只想让make重编译某些文件,而不是 ...

  8. 跟我学Makefile(六)

    shell 函数 :和反引号“`”是相同的功能 . shell 函数把执行操作系统命令后的输出作为函数返回. contents := $(shell cat foo) files := $(shell ...

  9. 跟我学Makefile(五)

    文件名操作函数 每个函数的参数字符串都会被当做一个或是一系列的文件名来对待. $(dir <names...>) 名称:取目录函数——dir. 功能:从文件名序列<names> ...

随机推荐

  1. Android Log缓冲区大小设置

    当手机没有连接PC时,手机log缓冲区仍然会保存指定大小的最新log,连接pc,通过adb logcat 仍然可以拿出来 如何查看log缓缓区的大小? 通过adb logcat -g 可以查看 C:\ ...

  2. linux alternatives命令详解

    alternatives是Linux下的一个功能强大的命令.只能在root权限下执行.如系统中有几个命令功能十分类似,却又不能随意删除,那么可以用 alternatives 来指定一个全局的设置. a ...

  3. JavaScript通知浏览器,更改通知数目

    http://lab.ejci.net/favico.js/ http://www.zhangxinxu.com/study/201607/web-notifications.html http:// ...

  4. 【CF662A】Gambling Nim 线性基

    [CF662A]Gambling Nim 题意:n长卡牌,第i张卡牌正面的数字是$a_i$,反面的数字是$b_i$,每张卡牌等概率为正面朝上或反面朝上.现在Alice和Bob要用每张卡牌朝上的数字玩N ...

  5. Windows Server 2008 R2之二从介质安装 AD DS

    可以使用 Ntdsutil.exe 为在域中创建的其他域控制器创建安装介质.通过从介质安装,可以最大程度地减少网络上目录数据的复制.有利于在远程站点中更高效地安装其他域控制器. 实验环境: 在Wind ...

  6. K-means中的K值选择

    关于如何选择Kmeans等聚类算法中的聚类中心个数,主要有以下方法(译自维基): 1. 最简单的方法:K≍sqrt(N/2) 2. 拐点法:把聚类结果的F-test值(类间Variance和全局Var ...

  7. Laravel 中的异常处理

    这篇文章里,我们将研究 Laravel 框架中最重要也最少被讨论的功能 -- 异常处理. Laravel 自带了一个异常处理类,它能够让你以简单.优雅的方式 report 和 render 异常. 文 ...

  8. zabbix中文乱码的问题

    在使用zabbix时,有时候会出现中文乱码的问题,如下: 因为zabbix自身对中文简体的支持不完善,需要我们手动的去上传新的字体进行替换: 1.在windows获取字体库文件 在Windows上的字 ...

  9. UI自动化--PageObjects(页面对象)

    核心的核心:减少了重复代码的数量,减少变更涉及面:做到如果UI发生更改,则只需在一个位置应用此修复程序. PageObject:将页面作为一个对象,进行封装,包括元素定位,封装获取各元素.操作的方法: ...

  10. vue报错 Module not found: Error: Cannot resolve 'file' or 'directory'

    炸了,我好写sell而组件,直接就用了,我的天哪 看你的写了吗,就用: Module not found: Error: Cannot resolve 'file' or 'directory' 页另 ...