详解Makefile变量

Makefile变量

1、特征

1)变量和函数的展开(除规则的命令行以外),是在make读取Makefile文件时进行的,这里的变量包括了使用“=”定义和使用的指示符“define”定义的变量。

2)可以用来代表一个文件名列表、编译选项列表、程序运行的选项参数列表、搜索文件的目录列表、编译输出的目录列表和我们所能够想到的事物。

3)变量名不能包括“:”、“#”、“=”、前置空白和尾空白的任何字符串。

4)对大小写敏感,注意区分。

5)有自动化变量的符号代表。

6)变量的引用与Shell脚本类似,使用美元符号($)和圆括号--()

2、分类

(1)自定义变量。 (常用)

例:

A = apple

B = I love China

C = $(A)tree  -----C = apple tree

(2)系统预定义变量。

CFLAGSCCMAKESHELL等,这些变量已经有了系统预定义好的值,我们也可以给它们重新赋值,如CC的默认值是gcc

<Linux>详解Makefile变量

(3)自动化变量。@^<使用较多)

<@?#等,这些特殊的变量之所以称为自动化变量,是因为它们的值会“自动地”发生变化,考虑普通的变量,只要不给它重新赋值,那么它的值是不变的。而自动化变量的值是不固定的,不能说@的值等于几,但是它的含义是固定的—@代表了其所在规则的目标的完整名称。

**************关于Makefile自动化变量及其变种的具体符号及其含义,参考博主博客《Makefile自动化变量及其变种》***********************

****************************************点击链接:http://blog.****.net/wu9797/article/details/77450395***************

3、定义方式

(1)递归定义方式。(常用)

例:

A = Love $(B)

B = China

在变量B出现之前,变量A的定义包含了对变量B的引用,由于A的定义方式是所谓的“递归”定义方式,因此当出现$(B)时会对全文件进行搜索,找到B的值并代进A中,A变量的结果为:“Love China”。

(2)直接定义方式。

B = China

A := I love $(B)

定义A是用的就是直接定义方式,即如果其定义里出现有队其他变量的引用,只会在其前面的语句进行搜寻,而不是搜索整个文件。所以,若:

A := I love $(B)

B = China

这样的话,定义AB值为空。

(3)条件定义方式。

判断一个变量是否已经定义,如果已经定义了则不做操作,若没有则定义其值。

例:

A = apple

A = China

A =的含义就是,如果在A之前没有定义,则定义为China。前面已定义了A,故A还是apple,维持原值。

(4)多行命令定义方式。

例:

define commands

echo “Hello!”

echo “Thanks.”

endef

语法格式:以define开头,以endef结束。其所要定义的变量名必须在指示符define的同一行之后。

4、操作方式

(1)追加变量的值。

例:

A = apple

A += tree

变量A的值就为apple tree了。

(2)修改变量的值。

例:

A = test1.c test2.c test3.c

B = $(A:%.c=%.o)

变零B的值就变成了test1.o test2.o test3.o

(3)override一个变量。 (较少使用)

例:

override CFLAGS += -Wall

指示符override存在的目的是为了使用户可以改变或者追加那些使用make的命令行指定的变量的定义,也就是说实现了在Makefile中增加挥着修改命令行参数的一种机制。

(4)导出变量。 (常用)

例:

export CFLAGS = -Wall -g

导出变量的作用:使该变量可以传递给子Makefile

对于默认会被传递给子Makefile的变量,可以使用unexport来阻止传递。

5、特殊变量

(1)VPATH      (常用)

用于指定Makefile中文件的备用搜寻路径:当Makefile中国的目标文件或依赖文件不在当前路径时,make会在此变量所指定的目录中搜寻。如果VPATH包含多个备用路径,使用空格或者冒号隔开(一般使用冒号)。

例:

VPATH = src1/:arc2/

all: a b

a:a.c   #如果make发现当前路径下不存在a.c,就会到VPATH中去找

gcc $^ -o [email protected]

b:b.c

gcc $^ -o [email protected]

 

注意vpath为一个指示符,可以灵活地为各种不同的文件指定不同的路径。

例:

vpath %.c =  src1/:arc2/ #指定本Makefile.c文件的可能路径

vpath %.h = include/  #指定本Makefile.h文件的可能路径

all:a b

a:a.c head.h

$(CC) $< -o [email protected]

b:b.c head.h

$(CC) $< -o [email protected]

(2)MAKE

当需要在Makefile中调用子Makefile时,需要用到MAKE变量,代表了当前系统中make软件的全路径。

例:

$MAKE-C subdir/

其中-C subdir/代表指定子Makefile所在目录。

(3)MAKEFLAGS (使用较少)

代表在执行make是的命令行参数,此变量默认会被传递给子Makefile

例:

all:

echo $(MAKEFLAGS)

如使用make -hello命令,则会显示出hellohello就是命令行参数。


参考书籍:林世霖《Linux环境编程图文指南》