zoukankan      html  css  js  c++  java
  • 一起学Makefile(四)

    变量的定义

    makefile中的变量,与C语言中的宏类似,它为一个文本字符串(变量的值,其类型只能是字符串类型)提供了一个名字(变量名)。

     

    变量的基本格式:

    变量名   赋值符   变量值

    变量名指的就是该变量的名字,是不包括“:”、“#”、“=”、前置空白和尾空白的任何字符串。需要注意的是,尽管在GNU make中没有对变量的命名有其它的限制,但定义一个包含除字母、数字和下划线以外的变量的做法也是不可取的,因为除字母、数字和下划线以外的其它字符可能会在以后的make版本中被赋予特殊含义,并且这样命名的变量对于一些shell来说不能作为环境变量使用。变量名是大小写敏感的。变量“foo”、“Foo”和“FOO”指的是三个不同的变量。Makefile传统做法是变量名是全采用大写的方式。推荐的做法是在对于内部定义定义的一般变量(例如:目标文件列表objects)使用小写方式,而对于一些参数列表(例如:编译选项CFLAGS)采用大写方式。 

    变量值,指的是变量所代表的内容,可以是一个文件名列表、编译选项列表、程序运行的选项参数列表、搜索源文件的目录列表、编译输出的目录列表和所有我们能够想到的事物。变量的值,其本质就是一个字符串。

    赋值符,有= 、 := 、 ?=和 +=四种格式,其中= 和 := 为基本定义类型, ?=和 +=为基于=的扩展定义类型。

    一个在makefile中定义变量的例子:

      objects = program.o foo.o utils.o

    变量的引用

    当我们定义了一个变量之后,我们就可以在makfile中的目标、依赖、命令中引用我们的变量;而所谓的变量引用,就是在引用变量名的地方,用变量所代表的内容,执行一个严格的文本替换过程(该过程也称为变量被展开的过程 ),替换掉变量的名字。

     变量的引用有以下几种方式:

    ${变量名}

    $(变量名)

    $单字符变量名 ,变量名仅包含一个字符,如$@ 、$^等

    一个在makefile中引用变量的例子:

    # 变量定义
    objects = program.o foo.o utils.o
    
    program : $(objects)          #在依赖中引用变量
        gcc -o program ${objects} #在命令中引用变量
    
    $(objects) : defs.h           #在目标中引用变量

     

    变量的分类与赋值

    根据变量定义时所使用的赋值操作符的不同,可以将变量分成两种类型(或者说是两种风格):

    递归展开式变量和直接展开式变量;

    使用赋值操作符= 、 += 和 ?=定义的变量都是递归展开式变量,使用赋值操作符 :=定义的变量为直接展开式变量

     两种变量类型的的最根本区别在于:变量值的求值时机,递归式变量的求值时机在于变量被引用时,直接展开式的求值时机在于变量被定义时。

     由于变量foo1的变量值是在执行echo命令时才求的值,所以foo1的值被递归的展开为Huh?; 而变量foo2的变量值在定义时就被求值了,此时由于变量bar的值为空,因此foo2的值也为空。

    注意:使用递归展开式的变量定义,可能会由于出现变量的递归定义而导致make陷入到无限的变量展开过程中,最终使make执行失败。

    += 和 ?=是基于=扩展而来的两种变量赋值操作符;

    += 称为追加赋值操作符,它实现对于一个已经存在定义的变量进行追加赋值,如下例子:

    ?=称为条件赋值的赋值操作符,被称为条件赋值为:只有此变量在之前没有赋值的情况下才会对这个变量进行赋值。看一下例子:

    特殊的变量

    在makefile 中用户除了可以自定义变量外,还可以使用make工具为我们提供的一些特殊的变量及用法。

    自动化变量:

    所谓自动化变量,就是在每条规则中,make自动为我们提供的用于指定规则各个组成部分的变量,一般情况下常用的有以下几个自动化变量:

    $@ -- 代表规则中的目标文件名

    $< -- 代表规则的第一个依赖的文件名

    $^ -- 代表规则中所有依赖文件的列表,文件名用空格分割

    说明:

    $字符在makefile中有特殊用途,因此如果要取消其特殊用途当成一个普通字符传递给echo命令执行,需要使用$$

    $@在bash shell中也有特殊用途,因此如果希望echo命令在bash中正常输出$@, 需要加上字符

    该makefile的最后一行first second third: 看起来有点奇怪,这是一条没有依赖和命令的多目标规则,读者可自行将它删除看有什么效果,并思考原因。  

    变量的替换引用

    变量的分类与赋值

     对于一个已经定义的变量,可以使用“替换引用”将其值使用指定的字符(字符串)进行替换。格式为$(VAR:A=B)或者${VAR:A=B},意思是,将变量“VAR”所表示的值中所有字符串“A”结尾的字符替换为“B”的字。“结尾”的含义是空格之前(变量值的多个字以空格分开)。而对于变量其它部分的“A”字符不进行替换。例如:

    在这个定义中,变量“objects”的值就为“a.c b.c c.c d.d”。使用变量的替换引用将变量“sources”以空格分开的值中的所有的字的尾字符“o”替换为“c”,其他部分不变,注意这里的d.d并不会被替换。

    使用变量修改前面的makefile

    #define variable of executable file
    executable := complicated
    
    #define variable of source document
    sources := main.c complicated.c
    
    #using repalce with a reference to a variable
    #and define the 'object' file list
    objects := $(sources:.c=.o)
    
    #Define compile command variables
    CC := gcc
    
    #Ultimate goal rule,generating complicate executor
    $(executable):$(objects)
    #using an automated variable to transfer compilation command
        $(CC) -o $@ $^
    
    #subrule 1 to generate main.o
    main.o : main.c
        $(CC) -o $@ -c $<
    
    #subrule 2 to generate complicated.o
    complicated.o  : complicated.c
        $(CC) -o $@ -c $<
  • 相关阅读:
    MS CRM 2011 RC中的新特性(4)——活动方面之批量编辑、自定义活动
    最近的一些有关MS CRM 2011的更新
    MS CRM 2011 RC中的新特性(6)——连接
    MS CRM 2011 RC中的新特性(7)—仪表板
    参加MS CRM2011深度培训课程——第一天
    MS CRM 2011插件调试工具
    MS CRM2011实体介绍(四)——目标管理方面的实体
    MS CRM 2011 RC中的新特性(3)——客户服务管理方面
    MS CRM 2011 RC中的新特性(8)—数据管理
    ExtAspNet 登陆
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11762960.html
Copyright © 2011-2022 走看看