有时我们需要对已经定义过的变量进行追加,可以使用+=进行这一操作,就像下面这样

    objects += another.o

该语句取objects变量的值,并在其后追加 another.o(结果会在原变量值和another.o之间加上一个空格,即使上述语句中+=和another.o之间没有空格或有多个空格),因此

    objects = main.o foo.o bar.o utils.o
objects += another.o

会将objects设置为main.o foo.o bar.o utils.o another.o

使用+=类似于:

    objects = main.o foo.o bar.o utils.o
objects := $(objects) another.o

但是在使用更为复杂的变量值时,这两种方式可能会有明显的差异

若对尚未定义过的变量进行操作时,+=等效于:=,定义了一个递归展开的变量.然而,当对已定义的变量进行+=操作时,实际进行的操作取决于该变量的类型(简单展开还是递归展开).关于两种变量类型请参考The Two Flavors of Variables

当使用+=追加变量时,实质就是在原先的定义上追加.

当对一个原先以:=或者::=定义的简单展开展变量进行+=操作时,make将会在追加之前将原变量展开

    variable := value
variable += more

等效于

    variable := value
variable := $(variable) more

另一方面,当对一个原先以=定义的递归展开变量进行+=操作时,make的表现与前一种情况有所不同,回想一下,当你定义一个循环展开变量时,make并不会立即展开变量值中包含的变量或函数引用,而是会照原样保留,只有在之后引用这个变量时,才会展开变量定义中所包含的引用.当对递归展开变量进行+=操作时,实际上make会直接在变量字面值(而不是展开后的值)上进行附加.

    variable = value
variable += more

大致相当于

    temp = value
variable = $(temp) more

当然,make并不会为此而实际定义temp.值得关注的是,当变量原始值包含对其他变量或函数的引用时,发生了什么,举个例子:

    CFLAGS = $(includes) -O
…
CFLAGS += -pg # enable profiling

第一行的CFLAGS定义包含了对另一个变量includes的引用.由于CFLAGS是用=定义的,所以它是一个循环展开变量,也就意味着make在处理CFLAGS的定义时并不会展开$(includes) -O.因此,也就意味着includes在真正生效之前不必被定义.includes只需在真正使用CFLAGS之前定义即可.如果我们试图使用除了+=之外的其他方法完成对CFLAGS的追加操作,或许会这样:

    CFLAGS := $(CFLAGS) -pg # enable profiling

这相当接近我们的目的,但并不完全是.使用:=会将CFLAGS重新定义为简单展开变量;也就意味着make会在重新为CFLAGS赋值之前展开$(CFLAGS) -pg,如果includes尚未定义,我们会得到 -O -pg,即使后来定义了includes也不会对CFLAGS产生影响.相反,使用+=会将CFLAGS设置为未展开的$(includes) -O -pg.因此也就会保留对includes的引用,所以只要在之后任何地方给出了includes的定义,对CFLAGS的引用$(CFLAGS)都会使用该值.

GNU make doc - 6.6 追加变量值的更多相关文章

  1. 解决debug到jdk源码时不能查看变量值的问题

    目录 如何跟踪jdk源码 1. 编译源码 2. 关联源码 3. 大功告成 如何跟踪jdk源码 看到这个标题大概大家都会在心里想谁还跟踪个源码呀,在eclipse中打个断点,以debug的方式运行,然后 ...

  2. $ORACLE_HOME变量值末尾多“/”惹的祸

    之前一直误以为$ORACLE_HOME变量的路径中末尾多写一个"/"不会有影响. 今天做实验时碰到一个情景,发现并不是这样. 环境:OEL 5.7 + Oracle 10.2.0. ...

  3. JavaScript判断变量值简单的方法

    今天在看一个动态web表单设计器的时候发现项目中的 一个写法 function sum_total(v){ if (!v) { v= 0; } } !v  这是什么写法?不过可以肯定的是,这是一种判断 ...

  4. axure设置变量值

    以登录框为例设置axure变量值 1.打开axure,打开新页面命名为login,拖入一个矩形背景,命名:登录背景图 2.拖入标签控件和输入框控件分别命名为用户名:.userName.密码:.pass ...

  5. 通过反射将变量值转为变量名本身ZZ

      这是.NET反射的一个有趣小例子:  通过反射将变量值转为变量名本身. 当然要先添加命名空间:using System.Reflection; 示例代码如下: class Program { st ...

  6. MFC一个类访问另一个类成员对象的成员变量值

    MFC中一个类要访问另外一个类的的对象的成员变量值,这就需要获得原来那个类对象的指针,其实有好几种方法都可以实现. 比如维护一个单例模式.设置静态变量等等.我们这里举个列子,实现多个类之间的相互访问. ...

  7. Shell脚本获得变量值作为新变量一部分的值

    最近使用shell写一个发布脚本时,由于shell编程是边学便用的缘故,经验不足,中间遇到一个问题,一个变量的值作为一个新变量的一部分,而我要根据变量获得新变量的值,以前没有遇到过.网络搜索一番,最后 ...

  8. JDK环境变量中dt.jar、tools.jar等变量值的作用

    变量名:CLASSPATH 变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar; tools.jar: 工具类 库,它跟我们程序中用到的 基础 ...

  9. python 交换变量值

    在其他语言中,交换两个变量值的时候,可以这样写: temp = a a = b b = temp 在Python中,我们可以简单的这样写: a,b=b,a 实验如下: >>> a=1 ...

随机推荐

  1. 如何用rflask快速初始化Flask Restful项目

    如何用rflask快速初始化Flask Restful项目 说明 多啰嗦两句 我们在创建flask项目的时候,使用pycharm创建出来的项目比较简陋,而且随着项目的功能完善,项目目录结构会比较多,多 ...

  2. 2、pycharm安装及相关配置

    PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试. 语法高亮.Project管理.代码跳转.智能提示.自动完成.单元测试.版本控制 ...

  3. RMQ算法使用ST表实现

    RMQ RMQ (Range Minimum Query),指求区间最小值.普通的求区间最小值的方法是暴力. 对于一个数列: \[ A_1,~ A_2,~ A_3,~ \cdots,~ A_n \] ...

  4. libc.so.6修改链接指向后导致系统无法使用的原因及解决方法

    https://www.cnblogs.com/weijing24/p/5890031.html http://man.linuxde.net/ldconfig

  5. win10搭建本地服务器(IIS)

    若想外网也可以访问使用NATAPP:https://natapp.cn/article/natapp_newbie 参考文章: https://segmentfault.com/a/119000001 ...

  6. ubuntu以root身份登录

  7. 7、EIGRP

    EIGRP Cisco私有协议1.高级距离矢量路由协议(混杂型hybrid)单播和组播结合,组播更新地址: 224.0.0.10 2.最快速收敛 (使用Diffusing Update 算法(DUAL ...

  8. linux中rz、rs命令无法执行的情况

    执行如下安装命令: yum install -y lrzsz

  9. 练习2-14 求奇数分之一序列前N项和 (15 分)

    练习2-14 求奇数分之一序列前N项和 (15 分) 本题要求编写程序,计算序列 1 + 1/3 + 1/5 + ... 的前N项之和. 输入格式: 输入在一行中给出一个正整数N. 输出格式: 在一行 ...

  10. 再谈typedef(重点为函数指针)

    有种很方便的写法. typedef int *p: p pointer: 这时直接把pointer带入原式中,取代p然后去掉typedef,得到的结果就是int * pointer: 哈哈,这样直接替 ...