zoukankan      html  css  js  c++  java
  • 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要吃什么  
     
  • 相关阅读:
    171. Excel Sheet Column Number (Easy)
    349. Intersection of Two Arrays (Easy)
    453. Minimum Moves to Equal Array Elements (Easy)
    657. Judge Route Circle (Easy)
    CSS笔记
    保存页面状态
    UI开发总结
    ubuntu 下配置munin
    反向代理配置
    JavaScript 高级程序设计第二版
  • 原文地址:https://www.cnblogs.com/wujing-hubei/p/5223155.html
Copyright © 2011-2022 走看看