码迷,mamicode.com
首页 > 其他好文 > 详细

变量和不同的赋值方式(四)

时间:2018-06-12 10:27:27      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:makefile   简单赋值(:=)   递归赋值(=)   条件赋值(?=)   追加赋值(+=)   

        在 makefile 中是支持程序设计语言中变量的概念的,makefile 中的变量只代表文本数据(字符串)。那么在 makefile 中的变量名的规则又有哪些呢?a> 变量名可以包含字符、数字以及下划线;b> 不能包含 ":" , "#" , "=" 或 " ";c> 变量名大小写敏感。下来我们来看看变量的定义和使用,如下

技术分享图片

        下来我们以代码为例来进行分析说明

CC := gcc
TARGET := hello.out

$(TARGET) : func.o main.o
    $(CC) -o $(TARGET) func.o main.o

func.o : func.c 
    $(CC) -o func.o -c func.c

main.o : main.c
    $(CC) -o main.o -c main.c

.PHONY : rebuild clean all

rebuild : clean all

all : $(TARGET)
    
clean : 
    rm *.o $(TARGET)

        我们来看看编译结果是否和之前一样

技术分享图片

        效果和之前是一样的,那么我们为何这样定义变量呢?在一些大型的工程项目中,我们可能要编译好几个版本,因此定义不同的 TARGET 便会编译出不同的版本。而且这种方法还有个好处就是编译器可以由我们自定义选择,比如我们将上面的 gcc 编译器换成 g++,则只需将 CC := gcc 换成 CC := g++,下来我们来看看编译效果

技术分享图片

        我们看到编译器已经换为 g++ 了。下来我们来讲讲 makefile 中变量的赋值方式,分为四种:a> 简单赋值(:=);b> 递归赋值(=);c> 条件赋值(?=);d> 追加赋值(+=)。那么不同的赋值方式其意义是不同的!下来我们来对这四种赋值方式进行一一的解释说明

        a> 简单赋值(:=):程序设计语言中的通用的赋值方式,只针对当前语句的变量是有效的。其用法如下

技术分享图片

        b> 递归赋值(=):赋值操作可能影响多个其他变量,所有与目标变量相关的其他变量都将受到影响。其用法如下

技术分享图片

        c> 条件赋值(?=):如果变量未定义,使用赋值符号中的值定义变量;如果变量已经定义,则赋值无效。其用法如下

技术分享图片

        d> 追加赋值(+=):原变量值之后加上一个新值,原变量值与新值之间由空格隔开。其用法如下

技术分享图片

        下来我们还是以代码为例来进行说明

# ex1 (:=)
x := foo
y := $(x)b
x := new

.PHONY : test

test :
    @echo "# ex1 (:=)"
    @echo "x => $(x)"
    @echo "y => $(y)"

        经过简单赋值后,x 就为 new 了,而 y 则应该为 foob。我们来看看编译效果

技术分享图片

        我们看到结果和我们所分析的是一样的。下来我们来看看递归赋值

# ex2 (=)
x = foo
y = $(x)b
x = new

.PHONY : test

test :
    @echo "# ex2 (=)"
    @echo "x => $(x)"
    @echo "y => $(y)"

        我们分析下,因为递归赋值是与目标相关的其他变量都会受到影响,那么 x 最后应该为 new,y 就应该为 newb。我们来看看编译结果

技术分享图片

        为了更加形象对递归赋值进行说明,我们编写代码如下

a = $(b)
b = $(c)
c = hello-makefile

.PHONY : test

test :
    @echo "# ex2 (=)"
    @echo "x => $(x)"
    @echo "y => $(y)"
    @echo "a => $(a)"
    @echo "b => $(b)"
    @echo "c => $(c)"

        我们定义 a 依赖于 b,而 b 依赖于 c。此时 c 为 hello-makefile,那么依赖于它的 b 也就变为 hello-makefile 了,此时依赖于 b 的 a 也就变为 hello-makefile 了。x 和 y 此时没定义,看看编译会报错吗?

技术分享图片

        编译是通过的,证明在 makefile 中是支持这样的写法的,x 和 y 没定义,自然也就为空了。那么 a,b,c 和我们所分析的是一样的。所以在 makefile 中我们一般是很少直接用递归赋值的,因为有可能会意想不到地改变依赖于它的目标。下来我们来看看条件赋值

# ex3 (?=)
x := foo
y := $(x)b
x ?= new

.PHONY : test

test :
    @echo "# ex3 (?=)"
    @echo "x => $(x)"
    @echo "y => $(y)"

        我们在最后对 x ?= new,意思是如果前面没定义的话,此时它便为 new。所以 x 最后应该为 foo,y 就应该为 foob。我们来看看编译结果

技术分享图片

        结果确实是这样的,一般我们会在新定义变量时采用这样的写法,以防止改变之前定义时的语义。最后看看追加赋值

# ex4 (+=)
x := foo
y := $(x)b
x += new

.PHONY : test

test :
    @echo "# ex4 (+=)"
    @echo "x => $(x)"
    @echo "y => $(y)"

        根据追加赋值的定义,它是直接在后面加上,但是有一个空格。所以 x 最后应该为 foo new,y 就应该为 foob。我们来看看编译结果

技术分享图片

        我们看懂啊效果确实是这样的,通过对四种赋值方式的学习,我们发现简单赋值是跟 C 语言中是一样的。追加赋值和 C++ 语言中的语义也是一样的,一般在大型项目中是不会采用递归赋值这种写法的。


        欢迎大家一起来学习 makefile,可以加我QQ:243343083

变量和不同的赋值方式(四)

标签:makefile   简单赋值(:=)   递归赋值(=)   条件赋值(?=)   追加赋值(+=)   

原文地址:http://blog.51cto.com/12810168/2128270

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!