makefile中的自动化变量$@,$%,$

 
makefile中的自动化变量$@,$%,$
 
自动化变量 
模式规则中,规则的目标和依赖文件名代表了一类文件名;规则的命令是对所有这
一类文件重建过程的描述,显然,在命令中不能出现具体的文件名,否则模式规则失去
意义。那么在模式规则的命令行中该如何表示文件,将是本小节的讨论的重点。 
假如你需要书写一个将.c 文件编译到.o 文件的模式规则,那么你该如何为gcc 书写
正确的源文件名?当然了,不能使用任何具体的文件名,因为在每一次执行模式规则时
源文件名都是不一样的。为了解决这个问题,就需要使用“自动环变量”,自动化变量
的取值是根据具体所执行的规则来决定的,取决于所执行规则的目标和依赖文件名。 
下面对所有的自动化变量进行说明:   www.2cto.com  
$@ 
表示规则的目标文件名。如果目标是一个文档文件(Linux中,一般称.a 文件为
文档文件,也称为静态库文件),那么它代表这个文档的文件名。在多目标模式
规则中,它代表的是哪个触发规则被执行的目标文件名。 
$% 
当规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则
的目标是“foo.a(bar.o)”,那么,“ $%”的值就为“bar.o”,“ $@ ”的值为“foo.a”。
如果目标不是静态库文件,其值为空。 
$< 
规则的第一个依赖文件名。如果是一个目标文件使用隐含规则来重建,则它代表
由隐含规则加入的第一个依赖文件。 
$? 
所有比目标文件更新的依赖文件列表,空格分割。如果目标是静态库文件名,代
表的是库成员(.o 文件)。   www.2cto.com  
$^ 
规则的所有依赖文件列表,使用空格分隔。如果目标是静态库文件,它所代表的
只能是所有库成员(.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中:
  O2表示优化选项,2表示最优优化,即编译器会优化你的程序;-o表示后边接的是文件名称;$@是Makefile的通配符,代指你前面指定的文件名,例如有规则%.o:%.c,那么$@表示xxx.o文件(xxx是你的源代码文件的名称前缀);$<表示搜索到的第一个匹配的文件,对于规则%.o:%.c,$<表示第一个找到的.c文件。简而言之,假设在一个文件夹下有若干.c文件,那么下面的规则:
%.o:%.c
<TAB>gcc
-O2 -o $@ $<
#<TAB>表示Tab键
表示把所有的.c文件编译成中间.o文件。
LDFLAGS是选项,LIBS是要链接的库
都是喂给ld的,只不过一个是告诉ld怎么吃,一个是告诉ld要吃什么  
 

随机推荐

  1. S2SH邮件注册激活后注册成功

    首先我的思路是这样的:①接收从客户端接收过来的数据(密码,用户名,邮箱) ②将密码进行MD5加密,然后将信息用"_"连接起来(用于后面分解) ③将信息交个一个工具类中实现生成邮件信 ...

  2. saas系统架构经验总结

    2B Saas系统最近几年都很火.很多创业公司都在尝试创建企业级别的应用 cRM, HR,销售, Desk Saas系统.很多Saas创业公司也拿了大额风投.毕竟Saas相对传统软件的优势非常明显. ...

  3. 2015年阿里巴巴蚂蚁金服校招JAVA研发工程师内推电话面试

    没想到阿里校招如此之早,虽然早已进入复习备战状态,但还是感觉有些措手不及...找了个在蚂蚁金服做HR的同学帮忙了内推,然后在最近的几天匆匆忙忙地复习JAVA(之前都把精力放在了数据结构.算法等基础上了 ...

  4. 对原生js的一些小尝试

    意图仿造JQ操作以及弄个个人工具箱,不断完善中,代码均为个人摸索,所以肯定会有不少不足的地方,希望读者们能提出来. var xzhUtils = { //-----DOM对象添加类----- //-- ...

  5. SSH会话连接超时问题

    目前大多数ssh服务是运行在Linux系统上的sshd服务.当访问终端在windows上时,各终端软件,如,putty,SecureCRT等,大多支持设置向服务器端自动发送消息,来防止终端定期超时.其 ...

  6. webpack学习

    // 一个常见的`webpack`配置文件 const webpack = require('webpack'); const HtmlWebpackPlugin = require('html-we ...

  7. &lbrack;LeetCode&rsqb; Number of Distinct Islands 不同岛屿的个数

    Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) conn ...

  8. org&period;apache&period;ibatis&period;binding&period;BindingException&colon; Invalid bound statement &lpar;not found&rpar;&colon; cn&period;e3mall&period;search&period;mapper&period;ItemMapper&period;getItemList

    java.lang.RuntimeException: org.apache.ibatis.binding.BindingException: Invalid bound statement (not ...

  9. 更新RecyclerView的好方法

    一般在使用RecyclerView的时候不免要修改RecyclerView的数据,使用notifyDataSetChanged()来刷新界面,但是当数据比较多,而只是修改了一点的数据,或者刷新比较频繁 ...

  10. IDEA或Webstorm设置Ctrl&plus;滚轮调整字体大小

    按Ctrl+Shift+A,出现搜索框 输入mouse: 点击打开这个设置:勾选 点击ok,之后就可以通过Ctrl+滚轮 调整字体大小了.

上一篇:Bootstrap学习 - 组件


下一篇:dedecms后台左侧菜单500错误怎么处理