||
变量是在makefile中定义的名字,用来代替一个文本字符串,该文本字符串称为的值。变量名是不包括“:”、“#”、“=”及空格的任何字符串。同时,变量名包含字母、数字及下划线以外的情况应尽可能避免,因为它们可能在将来被赋予特别的含义。变量名是大小写敏感的,推荐在makefile文件中使用小写字母作为变量名,预留大写字母作为控制隐含规则参数或用户重载命令选项参数的变量名。在具体要求下,这些值可以替代目标体、依赖文件、命令及makefile文件中的其他部分,在makefile文件中引用变量VAR的常用格式为“$(VAR)”。在makefile文件中变量的定义有两种方式: 一种是递归展开方式,另一种是简单方式。
递归展开方式的定义格式为:VAR=var。递归展开方式定义的变量是在引用该变量时进行替换的,即如果该变量包含了对其他变量的应用,则在引用该变量时一次性将内嵌的变量全部展开。虽然这种类型的变量能够很好地完成用户指令,但是它也有严重的缺点,如不能在变量后追加内容(因为语句“CFLAGS=$(CFLAGS) -o”在变量扩展过程中可能导致无穷循环)。
为了避免上述问题,简单扩展型变量的值在定义处展开,并且只展开一次,因此它不包含任何对其他变量的引用,从而消除了变量的嵌套应用。简单扩展方式的定义格式为:VAR:=var.
下面给出了一个使用了变量的makefile例子,这里用OBJS代替main.o和add.o,用CC代替gcc,用CFLAGS代替“-Wall –O -g”。这样在以后修改时,就可以只修改变量定义,而不用修改下面的引用实体,从而大大简化了维护makefile的工作量。
OBJS=main.o add.o
CC=gcc
CFLAGS=-Wall –O –g
add:$(OBJS)
$(CC)$(OBJS) –o add
main.o:main.c
$(CC)$( CFLAGS) –c main.c –o main.o
add.o:add.c
$( CC)$(CFLAGS) –c add.c –o add.o
clean:
Rm *.o
可以看到,此处变量是以递归展开方式定义的。
Makefile中的变量分为用户自定义变量、预定义变量、自动变量及环境变量。如上例中的OBJS就是用户自定义变量,自定义变量的值由用户自行设定。未经用户定义,在makefile中默认存在的变量则为预定义变量和自动变量,其中部分有默认值,当然用户可以对其进行修改。预定义变量包含了常见编译器、汇编器的名称及其编译选项。
可以看出,上例中的CC和CFLAGS是预定义变量,其中由于CC没有采用默认值,因此需要把“CC=gcc”明确列出来。
由于常见的GCC编译语句中通常包含了目标文件和依赖文件,而这些文件在makefile文件中的依赖关系一行已经有所体现。因此,为了进一步简写makefile文件的编写,引入了自动变量。自动变量通常可以代表编译语句中出现的目标文件和依赖文件等,并且具有本地含义(即下一语句中出现的相同变量代表的是下一语句中的目标文件和依赖文件)。自动变量的书写比较难记,但是在熟练了之后会非常方便,请大家结合下例中的自动变量改写的makefile进行记忆。
OBJS=main.o add.o
CC=gcc
CFLAGS=-Wall –O –g
add:$(OBJS)
$(CC)$^ –o $@
main.o:main.c
$(CC)$( CFLAGS) –c $< –o $@
add.o:add.c
$( CC)$(CFLAGS) –c $< –o $@
clean:
Rm *.o
另外,在makefile中还可以使用环境变量。使用环境变量的方法相对比较简单,make在启动时会自动读取系统当前已经定义了的环境变量,并且会创建与之具有相同名称和数值的变量。但是,如果用户在makefile中定义了相同名称的变量,则用户自定义变量将会覆盖同名的环境变量。
Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )
GMT+8, 2024-11-24 10:52 , Processed in 0.028678 second(s), 18 queries , Gzip On.
Powered by Discuz! X3.5
© 2001-2023 Discuz! Team.