原文:http://www.tanhp.com/index.php/archives/297/?utm_source=tuicool
编写makefile文件时通常会用到变量,makefile中定义变量的一般形式是:
变量名 赋值符 变量值
- 变量名习惯上只使用数字、字母、下划线,并且开头不能为数字,也可以使用其他字符,但不能使用以下字符:
:
,#
,=
,空白符; - 赋值符主要有四个:
=
,:=
,+=
,?=
;
makefile中的变量类似于C语言中的宏,且变量区分大小写。有一些变量时系统预定义的,如自动变量:$@
,$?
,$<
,$*
等。
1、引用变量
变量引用方式:$(变量名)
或${变量名}
,如果变量名是单字符,可以直接使用$变量名
。$
在makefile中有特殊含义,$$
表示字符$
。
2、定义变量
makefile中两种类型变量:递归展开变量和立即展开变量。通过=
赋值的变量时递归展开变量,:=
赋值的是直接展开变量。
(1)例如:
foo=$(bar)
bar=$(ugh)
ugh=Huh
all: echo $(foo)
整个变量替换过程如下:make执行echo
命令,$(foo)
被替换为$(bar)
,$(bar)
被替换为$(ugh)
,最后$(ugh)
被替换为Huh
。
好处是可以在未定义变量时就可以使用该变量,例如foo=$(bar)
提前使用了变量bar
;缺点是可能造成死循环,如CFLAGS=$(CFLAGS)-O
。
(2)使用:=
赋值变量时立即展开,例如:
x:=foo
y:=$(x) bar
x:=later
等价于
y:=foo bar
x:=later
这种类型的变量在定义时立即展开,而不是在引用时才展开。例如:
CFLAGS:=$(include_dirs) -O
include_dirs:=-lfoo -lbar
CFLAGS
的值是-O
,而不是-lfoo -lbar -O
,因为CFLAGS
在定义时立即展开,而此时include_dirs
还未定义,即值为空。
(3)条件赋值符?=
:只有在变量在之前没有赋值的情况下才会对这个变量进行赋值
(4)追加赋值符+=
:object += other.o
3、预定义变量
(1)预定于变量
AR 归档维护程序的名称,默认值为 ar。
ARFLAGS 归档维护程序的选项。
AS 汇编程序的名称,默认值为 as。
ASFLAGS 汇编程序的选项,默认值 -o。
CC C 编译器的名称,默认值为 cc。
CFLAGS C 编译器的选项。
CPP C 预编译器的名称,默认值为 $(CC) -E。
CPPFLAGS C 预编译的选项。
CXX C++ 编译器的名称,默认值为 g++。
CXXFLAGS C++ 编译器的选项。
MAKE make命令,默认值make.
例如:
gcc -c module.c
$(CC) -c module.c
(2)自动变量:make运行时动态改变
$* 不包含扩展名的目标文件名称。
$+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。
$< 第一个依赖文件的名称。
$? 所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。
$@ 目标的完整名称。
$^ 所有的依赖文件,以空格分开,不包含重复的依赖文件。
$% 如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称为
test.so(test.o),则 $@ 为 test.so,而 $% 为 test.o。