博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
makefile(四)使用变量
阅读量:7242 次
发布时间:2019-06-29

本文共 3610 字,大约阅读时间需要 12 分钟。

hot3.png

makefile可以使用变量,使用变量可以使makefile变的更加紧凑,但是makefile中的变量和通常意义上的变量有所不同。makefile文件中的变量代表了一个字符串。

一、使用普通变量

用户可以在makefile中定义变量,makefile文件中的变量代表了一个字符串。因此这些变量更像是C语言中的宏,在makefile文件执行过程中会展开在所使用的地方。makefile变量的命名可以包含字符、数字、下划线(可以是数字开头),并且大小写敏感。传统的makefile的变量名是全大写的命名方式。

makefile变量在声明的时候需要对其进行赋值,而在使用该变量时需要在变量名前加上$符号,例如$(VARNAME)。如果用户需要在makefile文件中使用$字符,则用$$来表示,这种应用多出现在对shell变量的使用上。

下面演示在makefile中使用变量:

objects =  main.o kdb.o command.o display.o \	insert.o serach.o files.o utils.oedit : $(objects)	gcc -o edit $(objects)main.o: main.c defs.h                       #生成 main.o	gcc -c main.ckdb.o: kdb.c defs.h command.h               #生成 kdb.o	gcc -c kdb.ccommand.o: command.c defs.h command.h       #生成 command.o	gcc -c command.cdisplay.o: display.c defs.h buffer.h        #生成 display.o	gcc -c display.cinsert.o: insert.c defs.h buffer.h          #生成 insert.o	gcc -c insert.cserach.o: serach.c defs.h buffer.h          #生成 serach.o	gcc -c serach.cfiles.o: files.c defs.h buffer.h command.h  #生成 files.o	gcc -c files.cutils.o: utils.c defs.h                     #生成 utils.o	gcc -c utils.cclean:    rm edit $(objects).PHONY : clean

在很多情况下,用户应将编译器及编译器选项定义为变量,这样可以增强makefile文件的灵活性。下面演示了使用这中方法的编译器工程的makefile文件,该makefile文件中的编译器和变异选项都是可以替换的。

CC = gccFLAGS = -cobjects =  main.o kdb.o command.o display.o \	insert.o serach.o files.o utils.oedit : $(objects)	$(CC) -o edit $(objects)main.o: main.c defs.h                       #生成 main.o	$(CC) $(FLAGS) main.ckdb.o: kdb.c defs.h command.h               #生成 kdb.o	$(CC) $(FLAGS) kdb.ccommand.o: command.c defs.h command.h       #生成 command.o	$(CC) $(FLAGS) command.cdisplay.o: display.c defs.h buffer.h        #生成 display.o	$(CC) $(FLAGS) display.cinsert.o: insert.c defs.h buffer.h          #生成 insert.o	$(CC) $(FLAGS) insert.cserach.o: serach.c defs.h buffer.h          #生成 serach.o	$(CC) $(FLAGS) serach.cfiles.o: files.c defs.h buffer.h command.h  #生成 files.o	$(CC) $(FLAGS) files.cutils.o: utils.c defs.h                     #生成 utils.o	$(CC) $(FLAGS) utils.cclean:    rm edit $(objects).PHONY : clean

当需要使用新的编译器对其进行编译时,只需要更改变量CC和变量FLAGS即可。

 

二、变量中的变量

在makefile文件中定义变量的值时,用户可以使用其他变量来构造变量的值。在makefile中使用变量定义变量值的方式有三种。

1.使用“=”操作符

该方式非常简单,=左侧是变量,右侧是变量的值,右侧变量的值可以定义在文件的任何一处。也就是说,右侧的变量不一定是已定义好的值,其也可以使用其后面定义的值。下面演示=的使用:

foo = $(bar)bar = $(ugh)ugh = hello?all :	echo $(foo)

执行结果为:

由上可知,makefile中的变量是可以使用后面的变量来定义的。这种定义变量值的方法有一个潜在的危险就是递归定义。例如:

a = $(b)b = $(a)

make会检测出这种错误。

2.使用“:=”操作符

使用“:=”操作符定义变量的值可以避免前述递归定义的危险。使用其定义变量时,前面的变量不能使用后面的变量,只能使用前面已定义好的变量。如果使用前面未定义变量,则该变量为空。下面演示这样的定义:

y := $(x) barx := $(foo)all :	echo $(y).PHONY : all

执行结果为:

输出的值是变量y的值,由于在定义y值时x的变量未定义,所以其值为空。

3.使用“?=”操作符

该操作符的含义是,如果变量之前没有被定义过,那么变量的值就被定义。如果变量的值之前已被定义过,则赋值语句什么也不做。下面实例演示了使用“?=”定义一个变量:

a := hellob ?= worlda ?= HELLOall :	echo $(a)	echo $(b).PHONY : all

执行结果如下:

由于变量a在a ?= HELLO之前已经被定义,所以a变量的值没有被改变。b变量在“b ?= world”之前没有定义,所以变量b的值被定义为world。

 

三、追加变量的值

makefile文件允许给一个变量追加一个值,其操作符为“+=”。由于makefile文件的变量本身是一个字符串,所以追加操作实际上是一个字符串链接操作,如下:

objects = main.o foo.o bar.oobjects += another.o

上面的代码等价于:

objects = main.o foo.o bar.oobjects = $(objects) another.o

如果变量之前没有定义过,“+=”操作符会自动变成“=”操作符,如果前一次变量定义时使用“:=”操作符,“+=”会以“:=”作为其操作符,如下:

objects := main.o foo.o bar.oobjects += another.o

等价于:

objects = main.o foo.o bar.oobjects := $(objects) another.o

 

四、自动化变量

makefile中允许使用自动化变量,这些变量的名称是由make工具已经定义好的。makefile中一共有7个自动化变量,如下:

自动化变量 表示的意义
$@ 表示规则中的目标文件集
$% 仅当目标是函数库文件时,表示规则中的目标成员名。例如,一个目标是foo.a(bar.o),那么,$%就是bar.o,$@就是foo.a。如果目标文件不是函数库文件,其值为空
$< 依赖列表中的第一个依赖的名字
$? 所有比目标新的依赖的合集,以空格分隔
$^ 所有依赖的集合,以空格分隔。如果依赖中有多个重复的,只保留一份
$+ 这个变量很像$^,也是所有依赖的集合,但是它不去除重复的依赖
$* 这个变量表示目标模式中“%”及之前的部分

 

转载于:https://my.oschina.net/daowuming/blog/778588

你可能感兴趣的文章
使用vue-axios和vue-resource解决vue中调用网易云接口跨域的问题
查看>>
background
查看>>
开源Pravega架构解析:如何通过分层解决流存储的三大挑战?
查看>>
JetBrains大力推广Kotlin为哪般?
查看>>
业务中台探索和实践:软件的根本问题
查看>>
VMware的云管理之道
查看>>
据Progress调查:2018年,70%的客户在使用NoSQL
查看>>
关于JavaScript 函数传参
查看>>
css学习(持续更新中)
查看>>
iOS开发秘笈:如何通过WebView监控提升WebAPP性能
查看>>
进入2016 -- 回顾我走过的编程之路
查看>>
货拉拉完成 3 亿美元 D 轮融资,2018 年全年业务量增长将近 200% ...
查看>>
Ceph Storage Cluster(CEPH存储集群) Configuration配置
查看>>
洛谷 P3369 BZOJ 3224 【模板】普通平衡树(Treap/SBT)
查看>>
logging模块配置笔记
查看>>
NLP 语料分类不均衡的解决办法
查看>>
【云周刊】第187期:阿里推出 PolarFS 分布式文件系统:将存储与计算分开,提升云数据库性能...
查看>>
1134. Vertex Cover (25)
查看>>
神经网络的激活函数总结
查看>>
[Guava源码日报](10)Iterables
查看>>