linux下的makefile教程(6)

2019-05-17 16:34

示符。其 语法是:

override =

override :=

当然,你还可以追加:

override +=

对于多行的变量定义,我们用define指示符,在define指示符前,也同样可以使用ovveri de指示符,如:

override define foo bar endef

六、多行变量

还有一种设置变量值的方法是使用define关键字。使用define关键字设置变量的值可以有

换行,这有利于定义一系列的命令(前面我们讲过―命令包‖的技术就是利用这个关键字 )。

define 指示符后面跟的是变量的名字,而重起一行定义变量的值,定义是以endef关键字

结束。其工作方式和―=‖操作符一样。变量的值可以包含函数、命令、文字,或是其它变

量。因为命令需要以[Tab]键开头,所以如果你用define定义的命令变量中没有以[Tab]键

开头,那么make就不会把其认为是命令。

下面的这个示例展示了define的用法:

define two-lines echo foo echo $(bar) endef

七、环境变量

make 运行时的系统环境变量可以在make开始运行时被载入到Makefile文件中,但是如果M

akefile中已定义了这个变量,或是这个变量由make命令行带入,那么系统的环境变量的值

将被覆盖。(如果make指定了―-e‖参数,那么,系统环境变量将覆盖Makefile中定义的 变量)

因此,如果我们在环境变量中设置了―CFLAGS‖环境变量,那么我们就可以在所有的Make

file中使用这个变量了。这对于我们使用统一的编译参数有比较大的好处。如果Makefile

中定义了CFLAGS,那么则会使用Makefile中的这个变量,如果没有定义则使用系统环境变

量的值,一个共性和个性的统一,很像―全局变量‖和―局部变量‖的特性。

当make嵌套调用时(参见前面的―嵌套调用‖章节),上层Makefile中定义的变量会以系

统环境变量的方式传递到下层的Makefile中。当然,默认情况下,只有通过命

令行设置的

变量会被传递。而定义在文件中的变量,如果要向下层 Makefile传递,则需要使用expro

t关键字来声明。(参见前面章节)

当然,我并不推荐把许多的变量都定义在系统环境中,这样,在我们执行不用的Makefile

时,拥有的是同一套系统变量,这可能会带来更多的麻烦。

八、目标变量

前面我们所讲的在Makefile中定义的变量都是―全局变量‖,在整个文件,我们都可以访

问这些变量。当然,―自动化变量‖除外,如―$<‖等这种类量的自动化变量就属于―规

则型变量‖,这种变量的值依赖于规则的目标和依赖目标的定义。

当然,我样同样可以为某个目标设置局部变量,这种变量被称为―Target-specific Vari

able‖,它可以和―全局变量‖同名,因为它的作用范围只在这条规则以及连带规则中,

所以其值也只在作用范围内有效。而不会影响规则链以外的全局变量的值。

其语法是:

:

: overide

可以是前面讲过的各种赋值表达式,如―=‖、―:=‖、―+=‖或

是―?=‖。第二个语法是针对于make命令行带入的变量,或是系统环境变量。

这个特性非常的有用,当我们设置了这样一个变量,这个变量会作用到由这个目标所引发

的所有的规则中去。如:

prog : CFLAGS = -g prog : prog.o foo.o bar.o

$(CC) $(CFLAGS) prog.o foo.o bar.o

prog.o : prog.c

$(CC) $(CFLAGS) prog.c

foo.o : foo.c

$(CC) $(CFLAGS) foo.c

bar.o : bar.c

$(CC) $(CFLAGS) bar.c

在这个示例中,不管全局的$(CFLAGS)的值是什么,在prog目标,以及其所引发的所有规则

中(prog.o foo.o bar.o的规则),$(CFLAGS)的值都是―-g‖

九、模式变量

在GNU的make中,还支持模式变量(Pattern-specific Variable),通过上面的目标变量

中,我们知道,变量可以定义在某个目标上。模式变量的好处就是,我们可以给定一种―

模式‖,可以把变量定义在符合这种模式的所有目标上。

我们知道,make的―模式‖一般是至少含有一个―%‖的,所以,我们可以以如下方式给所

有以[.o]结尾的目标定义目标变量:

%.o : CFLAGS = -O

同样,模式变量的语法和―目标变量‖一样:

:

: override

override同样是针对于系统环境传入的变量,或是make命令行指定的变量。

使用条件判断 ——————

使用条件判断,可以让make根据运行时的不同情况选择不同的执行分支。条件表达式可以

是比较变量的值,或是比较变量和常量的值。

一、示例

下面的例子,判断$(CC)变量是否―gcc‖,如果是的话,则使用GNU函数编译目

标。

libs_for_gcc = -lgnu normal_libs =

foo: $(objects) ifeq ($(CC),gcc)

$(CC) -o foo $(objects) $(libs_for_gcc) else

$(CC) -o foo $(objects) $(normal_libs) endif

可见,在上面示例的这个规则中,目标―foo‖可以根据变量―$(CC)‖值来选取不同的函

数库来编译程序。

我们可以从上面的示例中看到三个关键字:ifeq、else和endif。ifeq的意思表示条件语句

的开始,并指定一个条件表达式,表达式包含两个参数,以逗号分隔,表达式以圆括号括

起。else表示条件表达式为假的情况。endif表示一个条件语句的结束,任何一个条件表达

式都应该以endif结束。

当我们的变量$(CC)值是―gcc‖时,目标foo的规则是:

foo: $(objects)

$(CC) -o foo $(objects) $(libs_for_gcc)

而当我们的变量$(CC)值不是―gcc‖时(比如―cc‖),目标foo的规则是:

foo: $(objects)

$(CC) -o foo $(objects) $(normal_libs)

当然,我们还可以把上面的那个例子写得更简洁一些:

libs_for_gcc = -lgnu normal_libs =

ifeq ($(CC),gcc) libs=$(libs_for_gcc) else

libs=$(normal_libs) endif

foo: $(objects)

$(CC) -o foo $(objects) $(libs)

二、语法

条件表达式的语法为:

endif 以及:

else

endif

其中表示条件关键字,如―ifeq‖。这个关键字有四个。

第一个是我们前面所见过的―ifeq‖

ifeq (, ) ifeq '' '' ifeq \>\\>\ifeq \>\>' ifeq '' \>\

比较参数―arg1‖和―arg2‖的值是否相同。当然,参数中我们还可以使用make的函数。 如:

ifeq ($(strip $(foo)),) endif

这个示例中使用了―strip‖函数,如果这个函数的返回值是空(Empty),那么

-empty>就生效。

第二个条件关键字是―ifneq‖。语法是:

ifneq (, ) ifneq '' '' ifneq \>\\>\ifneq \>\'' ifneq '' \>\

其比较参数―arg1‖和―arg2‖的值是否相同,如果不同,则为真。和―ifeq‖类似。

第三个条件关键字是―ifdef‖。语法是:

ifdef

如果变量的值非空,那到表达式为真。否则,表达式为假。当然,

able-name>同样可以是一个函数的返回值。注意,ifdef只是测试一个变量是否有值,其并

不会把变量扩展到当前位置。还是来看两个例子:

示例一: bar = foo = $(bar) ifdef foo frobozz = yes else

frobozz = no endif

示例二: foo = ifdef foo frobozz = yes else

frobozz = no endif

第一个例子中,―$(frobozz)‖值是―yes‖,第二个则是―no‖。

第四个条件关键字是―ifndef‖。其语法是:

ifndef

这个我就不多说了,和―ifdef‖是相反的意思。

这一行上,多余的空格是被允许的,但是不能以[Tab]键做为

开始(不然就被认为是命令)。而注释符―#‖同样也是安全的。―else‖和―endif‖也

一样,只要不是以[Tab]键开始就行了。

特别注意的是,make是在读取Makefile时就计算条件表达式的值,并根据条件表达式的值

来选择语句,所以,你最好不要把自动化变量(如―$@‖等)放入条件表达式中,因为自

动化变量是在运行时才有的。

而且,为了避免混乱,make不允许把整个条件语句分成两部分放在不同的文件中。

使用函数 ————

在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智

能。make所支持的函数也不算很多,不过已经足够我们的操作了。函数调用后,函数的返

回值可以当做变量来使用。

一、函数的调用语法

函数调用,很像变量的使用,也是以―$‖来标识的,其语法如下:

$( ) 或是

${ }

这里,就是函数名,make支持的函数不多。是函数的参数,参数间

以逗号―,‖分隔,而函数名和参数之间以―空格‖分隔。函数调用以―$‖开头,以圆括

号或花括号把函数名和参数括起。感觉很像一个变量,是不是?函数中的参数可以使用变

量,为了风格的统一,函数和变量的括号最好一样,如使用―$(subst a,b,$(x))‖这样的

形式,而不是―$(subst a,b,${x})‖的形式。因为统一会更清楚,也会减少一些不必要的 麻烦。

还是来看一个示例:

comma:= , empty:=

space:= $(empty) $(empty) foo:= a b c

bar:= $(subst $(space),$(comma),$(foo))

在这个示例中,$(comma)的值是一个逗号。$(space)使用了$(empty)定义了一个空格,$(

foo)的值是―a b c‖,$(bar)的定义用,调用了函数―subst‖,这是一个替换函数,这

个函数有三个参数,第一个参数是被替换字串,第二个参数是替换字串,第三个参数是替

换操作作用的字串。这个函数也就是把$(foo)中的空格替换成逗号,所以$(bar)的值是― a,b,c‖。

二、字符串处理函数

$(subst ,, )

名称:字符串替换函数——subst。

功能:把字串中的字符串替换成。 返回:函数返回被替换过后的字符串。 示例:

$(subst ee,EE,feet on the s


linux下的makefile教程(6).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:木素提取制备及应用工艺技术

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: