Makefile入门(4)
版权所有,转载请注明:本文出自学与思linux编程网
在Makefile中使用变量
与其它的编程语言一样,在Makefile中也可以使用变量。Makefile中的变量名可以包含字母a-z,A-Z,数字0-9,下划线 _ 和其它一些字符,但我们不能在变量名中使用 $ = : # ? 和空格等这些在Makefile中有特殊含义的字符。变量名是字母大小写敏感的,即obj, Obj, OBJ是不同的变量。
变量定义时,我们直接用 变量名 = 变量值 这种方式,如:
OBJ = main.o file1.o file2.o
等号前后的空格可有可无,看您自己的习惯,不过我们c程序元可能更喜欢在等号左右都留上一个空格。
在使用变量的值时,我们不能直接写上变量名,我们需要在变量名前加上 $ 字符,且一般都要用{}或()把变量括起来,如果变量名只有一个字符我们也可以不用这两种括号把变量名括起来。变量可以使用在Makefile文件中的任何地方:规则中的目标体部分,依赖体部分,命令部分,或则给另一变量赋值,这些地方都可以使用变量,我们来看看下面这个简单的Makefile:
CC = arm-linux-gcc
PROJ_ROOT = /home/mike/proj
INCDIRS = -I. -I../ -I$(PROJ_ROOT)/include
CFLAGS = -Wall -O2 $(INCDIRS) -s
LIBROOT = $(PROJ_ROOT)/lib
LIBSLINK = -L./ -L$(LIBROOT)
APPS = stime
all: $(APPS)
stime: stime.o
$(CC) $(CFLAGS) -o $@ $^ ${LIBSLINK}
clean:
rm -f $(APPS) *.o
第一行定义了变量CC,其值为 arm-linux-gcc
第二行定义了变量PROJ_ROOT,其值为 /home/mike/proj
第三行定义了变量INCDIRS,被赋值为 -I. -I../ -I$(PROJ_ROOT)/include ,我们可以看到在定义这个变量时,使用了其它变量,make程序分析这个Makefile时在遇到$(PROJ_ROOT)时,就会把变量 PROJ_ROOT 的值插入到该处,就跟c语言中的宏的处理方式差不多,处理后得到INCDIRS的值:-I. -I../ -I/home/mike/proj/include 。后面的几个变量(CFLAGS, LIBROOT, LIBSLINK, APPS)类似。
第一条规则 all: $(APPS) 中的依赖体使用了变量,make程序处理时就会发生变量替换,替换后结果为 all: stime
第二条规则的命令部分使用了变量,还使用两个特殊的变量:$@ 和 $^ 稍后再说这两个变量,变量替换后为:
arm-linux-gcc -Wall -O2 -I. -I../ -I/home/mike/proj/include -s -o stime stime.o -L./ -L/home/mike/proj/lib
除了我们自己定义的变量外,make程序还会使用环境变量,自动变量和预定义变量。
环境变量
make程序启动时,就会读入环境变量,并保留这些环境变量名字而变成Makefile中的变量,比如,我们在shell环境 export CC=gcc 之后启动make,即使我们的Makefile中没得一个名字叫CC的变量,make程序启动时也会自动把CC这个变量引入进来,也就是我们在Makefile中无需定义它但却可以使用这个变量。
自动变量
自动变量也不需要我们定义,但我们可以在Makefile中使用,如前面看到的那两个特殊的变量$@和$^,还有一些常用的自动变量列入下表,其含义如下:
$@ : 规则中目标体的名字
$^ : 规则中所有的依赖体
$< : 规则中第一个依赖体
$? : 规则中所有时间晚于目标体的依赖体集合
如对应下面这条规则:
example: main.o file1.o file2.o
gcc $^ -o $@
我们先假定main.o和file2.o比example要新,则 $@ 的值为 example , $^ 的值为 main.o file1.o file2.o , $< 的值为 main.o , $? 的值为 main.o file2.o
注意:Makefile种的自动变量的作用范围是每一条规则,也就是说对另一条规则来说,这些自动变量的值也会有所不同,还有我们不能给这些变量赋值
预定义变量
预定义变量跟自动变量差不多,也是由make程序自动引入的,但它与自动变量有一点不同,预定义变量的作用范围是在整个Makefile文件,同一个预定义变量在不同的规则里其值是不会改变的,除非我们自己给它重新赋值(我们可以给预定义变量赋值,但不能给自动变量赋值)。常见的自定义变量有:
CC : C编译器,默认值为 cc
CPP : C预处理程序,默认值为 cpp
CFLAGS : 传给C编译器的标志,无默认值
CPPFLAGS : 传给C预处理程序的标志,无默认值
LDFLAGS : 传给连接器的标志,无默认值
RM : 文件删除命令,默认值为 rm -f
AR : 归档程序,默认值为 ar
