origin 函数 -- 告知变量的出生情况
origin 函数的作用是告诉你变量是哪里来的,其出生状况如何,他并不改变变量。其语法是:
$(origin <variable>)
上面,<variable> 为变量的名字,而不是引用,所以一般没有 $ 字符在前。origin 函数通过返回值来告诉你 <variable> 的出生情况。下面用实例说明:
1. 当从来未定义过该变量时,origin 函数返回 "undefined" 。如下面的 Makefile 代码:
all: @echo $(origin V)
运行输出:
$ make undefined
2. 如果该变量为环境变量,那么返回 "enviroment" 。如下面的 Makefile 代码:
all: @echo $(origin USER)
运行输出:
$ make environment
其中 USER 这个变量为系统定义的当前用户,使用 env 命令可以看到。
3. 如果变量是个默认定义,那么返回 "default"。如下面的 Makefile 代码:
all: @echo $(origin CC)
运行输出:
$ make default
4. 如果一个变量被定义在 Makefile 文件中,那么返回 "file" 。如下面的 Makefile 代码:
V := 1 all: @echo $(origin V)
运行输出:
$ make file
5. 如果变量来自命令行,那么返回 "command line" 。如下面的 Makefile 代码:
all: @echo $(origin MyVar)
运行方法:
$ make MyVar="Are you ok?" command line
6. 如果变量被 override 被重新定义过,那么返回 "override"。如下面的 Makefile 代码:
verride SHELL = /bin/sh all: @echo $(origin SHELL)
运行输出:
$ make override
上面,SHELL 原本是个环境变量,但在 Makefile 里被 override 指示符重定义过。
7. 如果变量是自动化变量(如 $@, $< 等),那么返回 "automatic" 。如下面的 Makefile 代码:
all: @echo $(origin @)
运行输出:
$ make automatic
这些信息对于我们编写Makefile是非常有用的,例如,假设我们有一个Makefile其包了一个定义文件Make.def,在Make.def中定
义了一个变量“bletch”,而我们的环境中也有一个环境变量“bletch”,此时,我们想判断一下,如果变量来源于环境,那么我们就把之重定义了,
如果来源于Make.def或是命令行等非环境的,那么我们就不重新定义它。于是,在我们的Makefile中,我们可以这样写:
ifdef bletch
ifeq "$(origin bletch)" "environment"
bletch = barf, gag, etc.
endif
endif
当
然,你也许会说,使用override关键字不就可以重新定义环境中的变量了吗?为什么需要使用这样的步骤?是的,我们用override是可以达到这样
的效果,可是override过于粗暴,它同时会把从命令行定义的变量也覆盖了,而我们只想重新定义环境传来的,而不想重新定义命令行传来的。 四、foreach 函数
foreach函数和别的函数非常的不一样。因为这个函数是用来做循环用的,Makefile中
的foreach函数几乎是仿照于Unix标准Shell(/bin/sh)中的for语句,或是C-Shell(/bin/csh)中的foreach
语句而构建的。它的语法是:
$(foreach <var>;,<list>;,<text>;)
这
个函数的意思是,把参数<list>;中的单词逐一取出放到参数<var>;所指定的变量中,然后再执
行<text>;所包含的表达式。每一次<text>;会返回一个字符串,循环过程中,<text>;的所返回的每
个字符串会以空格分隔,最后当整个循环结束时,<text>;所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数
的返回值。
所以,<var>;最好是一个变量名,<list>;可以是一个表达式,而<text>;中一般会使用<var>;这个参数来依次枚举<list>;中的单词。举个例子: names := a b c d
files := $(foreach n,$(names),$(n).o) 上面的例子中,$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是“a.o b.o c.o d.o”。
注意,foreach中的<var>;参数是一个临时的局部变量,foreach函数执行完后,参数<var>;的变量将不在作用,其作用域只在foreach函数当中。
|