Linux下C编程基础之:make工程管理器
为了避免上述问题,简单扩展型变量的值在定义处展开,并且只展开一次,因此它不包含任何对其他变量的引用,从而消除变量的嵌套引用。
递归展开方式的定义格式为:VAR=var。
简单扩展方式的定义格式为:VAR:=var。
make中的变量使用均使用的格式为:$(VAR)。
注意 | 变量名是不包括“:”、“#”、“=”以及结尾空格的任何字符串。同时,变量名中包含字母、数字以及下划线以外的情况应尽量避免,因为它们可能在将来被赋予特别的含义。 变量名是大小写敏感的,例如变量名“foo”、“FOO”、和“Foo”代表不同的变量。 推荐在makefile内部使用小写字母作为变量名,预留大写字母作为控制隐含规则参数或用户重载命令选项参数的变量名。 |
下面给出了上例中用变量替换修改后的makefile,这里用OBJS代替kang.o和yul.o,用CC代替gcc,用CFLAGS代替“-Wall-O–g”。这样在以后修改时,就可以只修改变量定义,而不需要修改下面的定义实体,从而大大简化了makefile维护的工作量。
经变量替换后的makefile如下所示:
OBJS=kang.oyul.o
CC=gcc
CFLAGS=-Wall-O-g
david:$(OBJS)
$(CC)$(OBJS)-odavid
kang.o:kang.ckang.h
$(CC)$(CFLAGS)-ckang.c-okang.o
yul.o:yul.cyul.h
$(CC)$(CFLAGS)-cyul.c-oyul.o
可以看到,此处变量是以递归展开方式定义的。
makefile中的变量分为用户自定义变量、预定义变量、自动变量及环境变量。如上例中的OBJS就是用户自定义变量,自定义变量的值由用户自行设定,而预定义变量和自动变量为通常在makefile都会出现的变量,它们的一部分有默认值,也就是常见的设定值,当然用户可以对其进行修改。
预定义变量包含了常见编译器、汇编器的名称及其编译选项。表3.15列出了makefile中常见预定义变量及其部分默认值。
表3.15 makefile中常见的预定义变量
预定义变量 | 含义 |
AR | 库文件维护程序的名称,默认值为ar |
AS | 汇编程序的名称,默认值为as |
CC | C编译器的名称,默认值为cc |
CPP | C预编译器的名称,默认值为$(CC)–E |
CXX | C++编译器的名称,默认值为g++ |
FC | Fortran编译器的名称,默认值为f77 |
RM | 文件删除程序的名称,默认值为rm–f |
ARFLAGS | 库文件维护程序的选项,无默认值 |
ASFLAGS | 汇编程序的选项,无默认值 |
CFLAGS | C编译器的选项,无默认值 |
CPPFLAGS | C预编译的选项,无默认值 |
CXXFLAGS | C++编译器的选项,无默认值 |
FFLAGS | Fortran编译器的选项,无默认值 |
可以看出,上例中的CC和CFLAGS是预定义变量,其中由于CC没有采用默认值,因此,需要把“CC=gcc”明确列出来。
由于常见的gcc编译语句中通常包含了目标文件和依赖文件,而这些文件在makefile文件中目标体所在行已经有所体现,因此,为了进一步简化makefile的编写,就引入了自动变量。自动变量通常可以代表编译语句中出现目标文件和依赖文件等,并且具有本地含义(即下一语句中出现的相同变量代表的是下一语句的目标文件和依赖文件)。表3.16列出了makefile中常见的自动变量。
表3.16 makefile中常见的自动变量
自动变量 | 含义 |
$* | 不包含扩展名的目标文件名称 |
$+ | 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件 |
$ | 第一个依赖文件的名称 |
$? | 所有时间戳比目标文件晚的依赖文件,并以空格分开 |
$@ | 目标文件的完整名称 |
$^ | 所有不重复的依赖文件,以空格分开 |
$% | 如果目标是归档成员,则该变量表示目标的归档成员名称 |
自动变量的书写比较难记,但是在熟练了之后使用会非常方便,请读者结合下例中的自动变量改写的makefile进行记忆。
OBJS=kang.oyul.o
CC=gcc
CFLAGS=-Wall-O-g
david:$(OBJS)
$(CC)$^-o$@
kang.o:kang.ckang.h
$(CC)$(CFLAGS)-c$-o$@
yul.o:yul.cyul.h
$(CC)$(CFLAGS)-c$-o$@
另外,在makefile中还可以使用环境变量。使用环境变量的方法相对比较简单,make在启动时会自动读取系统当前已经定义了的环境变量,并且会创建与之具有相同名称和数值的变量。但是,如果用户在makefile中定义了相同名称的变量,那么用户自定义变量将会覆盖同名的环境变量。
linux操作系统文章专题:linux操作系统详解(linux不再难懂)linux相关文章:linux教程
评论