makefile变量赋值

在定义变量的值时,我们可以使用其它变量来构造变量的值,在Makefile中有两种方式来在用变量定义变量的值。

先看第一种方式,也就是简单的使用“=”号,在“=”左侧是变量,右侧是变量的值,右侧变量的值可以定义在文件的任何一处,也就是说,右侧中的变量不一定非要是已定义好的值,其也可以使用后面定义的值。如:

foo = $(bar)
bar = $(ugh)
ugh = Huh?

all:
echo $(foo)

我们执行“make all”将会打出变量$(foo)的值是“Huh?”( $(foo)的值是$(bar),$(bar)的值是$(ugh),$(ugh)的值是“Huh?”)可见,变量是可以使用后面的变量来定义的。

这个功能有好的地方,也有不好的地方,好的地方是,我们可以把变量的真实值推到后面来定义,如:

CFLAGS = $(include_dirs) -O
include_dirs = -Ifoo -Ibar

当“CFLAGS”在命令中被展开时,会是“-Ifoo -Ibar -O”。但这种形式也有不好的地方,那就是递归定义,如:

CFLAGS = $(CFLAGS) -O

或:

A = $(B)
B = $(A)

这会让make陷入无限的变量展开过程中去,当然,我们的make是有能力检测这样的定义,并会报错。还有就是如果在变量中使用函数,那么,这种方式会让我们的make运行时非常慢,更糟糕的是,他会使用得两个make的函数“wildcard”和“shell”发生不可预知的错误。因为你不会知道这两个函数会被调用多少次。http://hovertree.com/menu/linux/

为了避免上面的这种方法,我们可以使用make中的另一种用变量来定义变量的方法。这种方法使用的是“:=”操作符,如:

x := foo
y := $(x) bar
x := later

其等价于:

y := foo bar
x := later

值得一提的是,这种方法,前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。如果是这样:

y := $(x) bar
x := foo

那么,y的值是“bar”,而不是“foo bar”。

上面都是一些比较简单的变量使用了,让我们来看一个复杂的例子,其中包括了make的函数、条件表达式和一个系统变量“MAKELEVEL”的使用:

ifeq (0,${MAKELEVEL})
cur-dir := $(shell pwd)
whoami := $(shell whoami)
host-type := $(shell arch)
MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
endif

关于条件表达式和函数,我们在后面再说,对于系统变量“MAKELEVEL”,其意思是,如果我们的make有一个嵌套执行的动作(参见前面的“嵌套使用make”),那么,这个变量会记录了我们的当前Makefile的调用层数。

下面再介绍两个定义变量时我们需要知道的,请先看一个例子,如果我们要定义一个变量,其值是一个空格,那么我们可以这样来:

nullstring :=
space := $(nullstring) # end of the line

nullstring 是一个Empty变量,其中什么也没有,而我们的space的值是一个空格。因为在操作符的右边是很难描述一个空格的,这里采用的技术很管用,先用一个 Empty变量来标明变量的值开始了,而后面采用“#”注释符来表示变量定义的终止,这样,我们可以定义出其值是一个空格的变量。请注意这里关于“#”的使用,注释符“#”的这种特性值得我们注意,如果我们这样定义一个变量:

dir := /foo/bar # directory to put the frobs in

dir这个变量的值是“/foo/bar”,后面还跟了4个空格,如果我们这样使用这样变量来指定别的目录——“$(dir)/file”那么就完蛋了。

还有一个比较有用的操作符是“?=”,先看示例:

FOO ?= bar

其含义是,如果FOO没有被定义过,那么变量FOO的值就是“bar”,如果FOO先前被定义过,那么这条语将什么也不做,其等价于:

ifeq ($(origin FOO), undefined)
FOO = bar
endif

推荐:http://www.cnblogs.com/roucheng/p/3470287.html

时间: 2024-09-28 16:03:04

makefile变量赋值的相关文章

makefile之变量赋值

makefile中变量赋值有4种方法: = ,   := ,  += ,  ?= = :直接赋值 变量 = 值 :=   :位置相关赋值 如果右值为一个值,那么它和=没区别,如果右值为变量,那么左边变量的值等于右边变量当前位置的值,什么意思呢? a = abc b = $(a) a = jkl all: @echo $(b) .PHONY:all 执行这个makefile,输出 b的值为jkl,  在 b = $(a) 这句中,变量a的值被延迟展开,即由变量a最后一条赋值语句 a = jkl 决

Makefile中变量赋值的方式

Makefile中的"="":="."?="和"+="区别是:"="是直接给变量赋值.":="是将":="右边中包含的变量直接展开给左边的变量赋值."?="是在该变量没有被赋值 的情况下为其赋值."+="是给该变量追加值.例:a = 1b = 2c := $(a) 3d = 4d ?= 5b += 6结果:a=1c=1 3d=4

shell 的特性:命令行展开,变量赋值,以及文件层次标准(history)

bash默认会保存以前执行过的命令列表 当前shell的进程保存在缓冲区中 缓冲区中的命令会在shell退出后保存在文件中    .bash history 使用上下箭头可以翻看此前执行过的命令 history: !数字  :  执行history中第数字条命令 !!   :  上一条命令 !-数字:表示执行命令列表中的倒数第数字条命令 ESC .  : 执行上个命令的最后参数 ! string:执行命令列表中最后一个以string开头的命令 - d :删除第数字条记录 -c:清空history

Oracle ->> 变量赋值 Demo

刚学Oracle,学习学习别人的代码.这段代码时从下面的博文中摘取的:http://www.cnblogs.com/mq0036/p/4155774.html declare l_dept integer := 20; currtime date := sysdate; l_nam varchar2(20) := to_char(add_months(trunc(sysdate),-12),'yyyymmdd'); -- to_char(sysdate,'MM')-13; type num_li

.net开发环境的认识,控制台程序的创建,输出,输入,定义变量,变量赋值,值覆盖,值拼接,值打印 两种数据类型,整形类型转换

首先感谢向立凯老师带我走进.net这个很好的软件开发程序.通过两天的学习在这个领域的了解也多了很多,让大家先了解一下c#语言 c#是一种全新且简单.安全.快捷面向对象的程序设计语言.是专门为.net应用开发的语言..net的开发都基于一个统一的开发环境 Visual Studio.net.下面我们来看看怎么在Visual Studio.net.下创建以新的项目: 1.打开 2.新建一个项目 通过执行文件-新建-项目菜单命令,会弹出一个新建项目对话框.在这个对话框中选择开发语言为c#,选择框架版本

2017-2-17 c#基础学习 (控制台程序的创建,输出,输入,定义变量,变量赋值,值覆盖,值拼接,值打印)

1 控制台程序的创建 > 新建项目  ,选择 c#,  框架选择4.0 , 选择控制应用台程序, 选择文件保存位置 修改名字. 2 c#输出与输入 >在main函数中编写代码 >在编写时可以先插入Console.ReadLine();防止程序闪退 > Console.Write("实例语句");//不换行输出 Console.WriteLine("示例语句");//换行输出 Console.ReadLine();//等待用户输入 防止闪退 结

JavaScript 变量赋值

在js中经常会遇到将一个变量赋值给一个新的变量这种情况,这对于基本类型很容易去实现,直接通过等号赋值就可以了,对于引用类型就不能这样了.(注:像函数,正则也可以直接通过等号赋值) 这里我写了一个复制值的函数,可以进行深度复制,也能进行浅复制,要进行深度复制只需要将第二个参数设置为true即可 function clone(data,deep){ var cloneData = undefined; var data = arguments[0],deep = arguments[1]; if(!

Unity3D除了在编辑器里,怎么用代码给一个Texture类型的变量赋值

resource.load上来一张贴图就行. ? 1 2 3 4 5 6 7 8 9 using UnityEngine; using System.Collections; public class example : MonoBehaviour {     void Start() {         GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube);         go.renderer.material.mai

Python变量赋值的秘密

在Python中,我们令一个变量等于另外一个变量时,并不是把值传递给它,而是直接把指向的地址更改了.我们想要查看一个变量在内存中的地址,可以通过id(变量) 来查看.我们通过一个小例子来看看这个有趣的过程. >>> x = 12 >>> y= 13 >>> id(x) 1865402384 >>> id(y) 1865402416 >>> x = y >>> id(x) 1865402416 >