zoukankan      html  css  js  c++  java
  • make的变量及赋值运算

    在make文件的书写中,为了简化文件,常常会使用变量:

    make的规则:

    目标文件:依赖文件列表

      命令构建集

    无论是目标文件,还是依赖文件列表,还是命令构建合集中都可以使用变量:

    make中的变量主要有两种:自定义变量和内置make变量:

    1、自定义变量后,可以在 Makefile中使用该变量。变量的引用方式为:“ $( VARIABLE_NAME)”或者“ ${ VARIABLE_NAME }”来引用一个变量的定义。

      例如:

      foo = FLL

      “ $(foo) ”或者“ ${foo}”就是取变量 foo的值FLL。

    2、自动化变量,变量名只包含了一个或者很少的几个特殊的字符(符号)。称它们为自动化变量。像“ $<”、“ $@”、“ $?”、“ $^*”

      $@:规则的目标文件名。如果目标是一个档案成员,则变量‘$@’ 档案文件的文件名。对于有多个目标的格式规则(参阅格式规则简介),变量‘$@’是那个导致规则命令运行的目标文件名。

      $%:当目标是档案成员时,该变量是目标成员名,参阅使用make更新档案文件。例如,如果目标是‘foo.a(bar.o)',则‘$%'的值是‘bar.o',‘$@'的值是‘foo.a'。如果目标不是档案成员,则‘$%'是空值。

      $<:第一个依赖的文件名。如果目标更新命令来源于隐含规则,该变量的值是隐含规则添加的第一个依赖。参阅使用隐含规则。

      $?:所有比目标‘新’的依赖名,名字之间用空格隔开。对于为档案成员的依赖,只能使用已命名的成员。参阅使用make更新档案文件。

      $^:所有依赖的名字,名字之间用空格隔开。对于为档案成员的依赖,只能使用已命名的成员。参阅使用make更新档案文件。对同一个目标来说,一个文件只能作为一个依赖,不管该文件的文件名在依赖列表中出现多少次。所以,如果在依赖列表中,同一个文件名出现多次,变量‘$^’的值仍然仅包含该文件名一次。

      $+:该变量象‘$^',但是,超过一次列出的依赖将按照它们在makefile文件中出现的次序复制。这主要的用途是对于在按照特定顺序重复库文件名很有意义的地方使用连接命令。

      $*:和隐含规则匹配的径,参阅格式匹配。如果一个目标为‘dir/a.foo.b',目标格式规则为:‘a.%.b' ,则stem为‘dir/foo'。在构建相关文件名时stem 十分有用。在静态格式规则中,stem是匹配目标格式中字符‘%’的文件名中那一部分。在一个没有stem具体规则中;变量‘$*' 不能以该方法设置。如果目标名以一种推荐的后缀结尾(参阅过时的后缀规则),变量‘$*'设置为目标去掉该后缀后的部分。例如,如果目标名是‘foo.c',则变量‘$*' 设置为‘foo', 因为‘.c' 是一个后缀。GNU make 处理这样奇怪的事情是为了和其它版本的make兼容。在隐含规则和静态格式规则以外,您应该尽量避免使用变量‘$*'。在具体规则中如果目标名不以推荐的后缀结尾,则变量‘$*’在该规则中设置为空值。上面列举的变量中,有四个变量的值是单个文件名。三个变量的值是文件名列表。这七个变量都有仅仅存放文件的路径名或仅仅存放目录下文件名的变体。变量的变体名是由变量名追加字母‘D’或‘F’构成。

      `$(@D)':目标文件名中的路径部分,结尾斜杠已经移走。如果变量`$@'的值是`dir/foo.o',变体 `$(@D)'的值是`dir'。如果变量`$@'的值不包含斜杠,则变体的值是`.'。

      `$(@F)':目标文件名中的真正文件名部分。如果变量`$@'的值是`dir/foo.o',变体  `$(@F)'的值是` foo.o '。`$(@F)' 等同于 `$(notdir $@)'

      `$(*D)' `$(*F)':stem(径)中的路径名和文件名;在这个例子中它们的值分别为:`dir' 和 `foo' 。

      `$(%D)' `$(%F)':档案成员名中的路径名和文件名;这仅对采用‘archive(member)’形式的档案成员目标有意义,并且当成员包含路径名时才有用。参阅档案成员目标。

      `$(<D)' `$(<F)':第一个依赖名中的路径名和文件名。

      `$(^D)' `$(^F)':所有依赖名中的路径名和文件名列表。

      `$(?D)' `$(?F)':所有比目标‘新’的依赖名中的路径名和文件名列表。

    在make中有四种方式对变量赋值:

    1. :=运算符,如MAKE_DEPEND := $(CC) -M

        这种方式叫做“简单展开”,因为在读到makefile中的这一行时 等号右边就立即被展开了,等号右边引用的所有变量(如例子中的CC)也会被立即展开。其行为与一般编程和脚本语言相同。
        当等号右边引用的变量(如例子中的CC)还没有被定义时,它被展开成空(nothing)而不是空格之类。

    2. =运算符,如MAKE_DEPEND = $(CC) -M

        这种方式叫做“递归展开”,直到该变量被使用时等号右边的内容才会被展开,其实叫做“迟滞展开”更合适。神奇的是,这种展开方式可以不按顺序定义变量。比如:
    MAKE_DEPEND = $(CC) -M
    ...
    # Some time later
    CC = gcc
    只要在此之前没有引用过 MAKE_DEPEND就没问题。

        另外,不止是 “迟滞展开”,事实上每次使用该变量,等号右边的内容都会被重新展开。

    3. ?=运算符,如OUTPUT_DIR ?= $(PROJECT_DIR)/out

        这种方式叫“条件展开”,只有当OUTPUT_DIR 还没有被定义过时才进行赋值,否则什么都不做。这种方式在处理环境变量是特别有用。

    4. +=运算符,如OUTPUT_DIR += $(PROJECT_DIR)/out

       “追加”方式。 其主要目的是给“递归展开”的变量追加内容。因为简单变量可以用simple := $(simple) new stuff的方式来追加内容;而对于递归展开的变量,recursive = $(recursive) new stuff会导致循环引用。这种情况只能用+=运算符。 

  • 相关阅读:
    大公司?小公司?
    git 学习笔记
    django学习笔记
    web servieces 学习小栗子
    python列表推导式
    什么叫事务,事务的特性
    监听问题汇总
    oracle数据库导入导出
    ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务--解决办法(转)
    目标修正
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/13993314.html
Copyright © 2011-2022 走看看