分享

origin 函数 -- 告知变量的出生情况

 WUCANADA 2013-02-11

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函数当中。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多