makefile中的自动化变量 【转】
转自:http://blog.chinaunix.net/uid-28458801-id-3495215.html
自动化变量
模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这
一类文件重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去
意义。那么在模式规则的命令行中该如何表示文件,将是本小节的讨论的重点。
假如你需要书写一个将.c 文件编译到.o 文件的模式规则,那么你该如何为gcc 书写
正确的源文件名?当然了,不能使用任何具体的文件名,因为在每一次执行模式规则时
源文件名都是不一样的。为了解决这个问题,就需要使用“自动环变量”,自动化变量
的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名。
下面对所有的自动化变量进行说明:
$@
表示规则的目标文件名。如果目标是一个文档文件(Linux中,一般称.a 文件为
文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式
规则中,它代表的是哪个触发规则被执行的目标文件名。
$%
当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则
的目标是“foo.a(bar.o)”,那么,“ $%”的值就为“bar.o”,“ $@ ”的值为“foo.a”。
如果目标不是静态库文件,其值为空。
$<
规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表
由隐含规则加入的第一个依赖文件。
$?
所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代
表的是库成员(.o 文件)。
$^
规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的
只能是所有库成员(.o 文件)名。一个文件可重复的出现在目标的依赖中,变量
“$^”只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。
$+
类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时库
的交叉引用场合。
$*
在模式规则和静态模式规则中,代表“茎”。“茎”是目标模式中“% ”所代表的
部分(当文件名中存在目录时,“茎”也包含目录(斜杠之前)部分,可参考 10.5.4
模式的匹配 一小节)。例如:文件“dir/a.foo.b”,当目标的模式为“a.%.b ”时,
“$* ”的值为“dir/a.foo ”。“茎”对于构造相关文件名非常有用。
自动化变量“$* ”需要两点说明:
? 对于一个明确指定的规则来说不存在“茎”,这种情况下“$* ”的含义发
生改变。此时,如果目标文件名带有一个可识别的后缀(参考 10.7 后
缀规则 一节),那么“$* ”表示文件中除后缀以外的部分。例如:“foo.c”
则“$* ”的值为:“foo ”,因为.c 是一个可识别的文件后缀名。GUN make
对明确规则的这种奇怪的处理行为是为了和其它版本的make兼容。通
常,在除静态规则和模式规则以外,明确指定目标文件的规则中应该避
免使用这个变量。
? 当明确指定文件名的规则中目标文件名包含不可识别的后缀时,此变量
为空。
自动化变量“$?”在显式规则中也是非常有用的,使用它规则可以指定只对更新
以后的依赖文件进行操作。例如,静态库文件“libN.a ”,它由一些.o 文件组成。这个规
则实现了只将更新后的.o 文件加入到库中:
lib: foo.o bar.o lose.o win.o
ar r lib $?
以上罗列的自动量变量中。其中有四个在规则中代表文件名($@ 、$<、$%、$* )。
而其它三个的在规则中代表一个文件名列表。GUN make 中,还可以通过这七个自动化
变量来获取一个完整文件名中的目录部分和具体文件名部分。在这些变量中加入“D”
或者“F”字符就形成了一系列变种的自动环变量。这些变量会出现在以前版本的make
中,在当前版本的make中,可以使用“dir”或者“notdir”函数来实现同样的功能(可
参考 8.3 文件名处理函数 一节)。
$(@D)
表示目标文件的目录部分(不包括斜杠)。如果“$@ ”是“dir/foo.o ”,那么“$(@D) ”
的值为“dir”。如果“$@ ”不存在斜杠,其值就是“. ”(当前目录)。注意它和 函
数“dir”的区别!
$(@F)
目标文件的完整文件名中除目录以外的部分(实际文件名)。如果“$@ ”为
“dir/foo.o ”,那么“$(@F) ”只就是“foo.o”。“$(@F) ”等价于函数“$(notdir
$@) ”。
$(*D)
$(*F)
分别代表目标“茎”中的目录部分和文件名部分。
$(%D)
$(%F)
当以如“archive(member) ”形式静态库为目标时,分别表示库文件成员
“member”名中的目录部分和文件名部分。它仅对这种形式的规则目标有效。
$(<D)
$(<F)
分别表示规则中第一个依赖文件的目录部分和文件名部分。
$(^D)
$(^F)
分别表示所有依赖文件的目录部分和文件部分(不存在同一文件)。
$(+D)
$(+F)
分别表示所有依赖文件的目录部分和文件部分(可存在重复文件)。
$(?D)
$(?F)
分别表示被更新的依赖文件的目录部分和文件名部分
在讨论自动化变量时,为了和普通变量(如:“CFLAGS ”)区别,我们直接使用了
“$<”的形式。这种形式仅仅是为了和普通变量进行区别,没有别的目的。其实对于
自动环变量和普通变量一样,代表规则第一个依赖文件名的变量名实际上是“< ”,我
们完全可以使用“$(<) ”来替代“$<”。但是在引用自动化变量时通常的做法是“$<”,
因为自动化变量本身是一个特殊字符。
GUN make同时支持“Sysv”特性,允许在规则的依赖列表中使用特殊的变量引
用(一般的自动化变量只能在规则的命令行中被引用)“$$@”、“$$(@D)”和“$$(@F)”
(注意:要使用“$$”),它们分别代表了“目标的完整文件名”、“目标文件名中的目
录部分”和“目标的实际文件名部分”。这三个特殊的变量只能用在明确指定目标文件
名的规则中或者是静态模式规则中,不用于隐含规则中。另外Sysv make 和GNU make
对规则依赖的处理也不尽相同。Sysv make对规则的依赖进行两次替换展开,而GUN
make对依赖列表的处理只有一次,对其中的变量和函数引用直接进行展开。
自动化变量的这个古怪的特性完全是为了兼容Sysv 版本的makefile文件。在使用
GNU make 时可以不考虑这个,也可以在Makefile中使用伪目标“.POSIX ”来禁止这一
特性
makefile中的自动化变量 【转】的更多相关文章
- makefile中的自动化变量$@,$%,$
转自:http://www.2cto.com/os/201302/191344.html makefile中的自动化变量$@,$%,$ 自动化变量 模式规则中,规则的目标和依赖文件名代表了一 ...
- Makefile中几种变量赋值运算符
Makefile中几种变量赋值运算符: = :最简单的赋值 := :一般也是赋值 以上这两个大部分情况下效果是一样的,但是有时候不一样. 用 = 赋值的变量,在被解析时他的值取决于最 ...
- Makefile 自动化变量
Makefile中常用自动化变量解释如下: $@------规则的目标文件名 $<------规则的第一个依赖项文件名 $^------规则的所有依赖文件列表,以空格隔开. $?-------所 ...
- makefile中使用变量
makefile里的变量就像一个变量,变量的作用主要如下: (1)保存文件名列表. (2)保存编译器的参数. makefile中的变量是用一个字符串在makefile中定义的,这个文本串就是变量的值. ...
- 关于makefile中变量的多次赋值以及override指令
1 基本原则如下 1.1 原则1 变量的普通赋值是有先后顺序的,后面的赋值会覆盖掉前面的赋值. 1.2 原则2 使用的时候,用的是其前面最后的赋值,就算其后面有使用了override指令的赋值也不会影 ...
- Makefile中的变量和shell变量
我们在写makefile时 多多少少会用到shell脚本, 对于变量的在shell中的使用有一些要注意的细节.让我们从一个简单的makefile来看看. 注意makefile中一定要有一个目标,且一定 ...
- Linux makefile教程之使用变量五[转]
使用变量 ———— 在 Makefile中的定义的变量,就像是C/C++语言中的宏一样,他代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地展开在所使 用的地方.其与C/C++所不同 ...
- linux $ 类型变量 及Makefile 中 $ 类型变量的含义
Shell 命令中: $$: shell pid $!: pid of the last process running in shell $?: shell command return code ...
- Makefile中支持的函数大全
一.描述 Makefile的函数调用,很像变量的使用,也是以"$"来标识的,其语法如下: $(<function> <arguments> ) 或是 ${& ...
随机推荐
- django-CSRF verification failed. Request aborted
现象: 解决办法1: 在view.py文件中设置如下: from django.views.decorators.csrf import csrf_exempt @csrf_exempt #再写下面的 ...
- Noip2008双栈排序
[问题描述] 用两个栈使一个1...n的排列变得有序.一共有四个操作: A.stack1.push() 读入一个放入栈一 B.stack1.pop() 弹出栈一放入输出序列 C.stack2.push ...
- Matlab验证公式取值范围
一.问题来源 t = 2xy/(x+y);融合相似度和信任度,我需要验证值域是不是[0,1]: 二.求解 clear all; clc; %linspace(0:1,0.1)这样是错的,第三个参数是段 ...
- JS 时分秒验证
- 【转载】在程序中动态改变static text控件的caption值
方法1,给STATIC控件取个名字叫IDC_STATICTITLE 然后在ClassWizard中设定一个控件变量给它叫m_statictitle 然后用m_statictitle.SetWindow ...
- CSL概述(翻译总结自TI官方文档)
一.简单介绍 CSL是函数,宏和符号常数的集合,用来控制和配置片上外设.(Chip Support Library) 每一个外设都有自己对应的CSL模块.每个模块有自己的支持符,来表示对于给定的设备, ...
- 常用正则表达式(匹配URL/email/number)
var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/ ...
- 浅谈MySQL索引背后的数据结构及算法【转】
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- hadoop命令行命令
1. bin/hadoop fs -ls / 查看hdfs根目录下的文件 2. bin/hadoop fs -ls /user 查看user下文件 /就是根目录的意思.
- Python中编码问题?
一.键盘输入 raw_input('请输入:'.decode('utf-8').encode('gbk'))raw_input(unicode('请输入:','utf-8').encode('gbk' ...