MyException - 我的异常网
当前位置:我的异常网» 项目管理 » 《GNU make项目管理》札记-变量与宏(1)

《GNU make项目管理》札记-变量与宏(1)

www.myexceptions.net  网友分享于:2015-02-08  浏览:0次
《GNU make项目管理》笔记--变量与宏(1)

make包含两种语言。第一种语言用来描述工作与必要条件所组成的依存图。第二种语言是宏语言,用来进行文字替换。像

C预处理器,m4以及宏汇编器。

一个变量名称几乎可以由任何字符自称。包括大部分的标点符号,即使空格也可以使用,但应该避免这么做。事实上只有:

、#和=等字符不允许使用在变量名称中。

变量名称是区分大小写的。要取得某个变量的值,请使用$()括住该变量的名称,有一个特例:变量名称若为单一字母(letter)

则可以省略圆括号,所以请直接使用$letter。

你还可以使用花括号来扩展变量,例如${CC}.现代化的makefile多半使用园括号。

当 变量用来表示用户在命令行上或环境中所定义的常数时,习惯上会全部以大写来编写其名称,单词之间以下划线符号_隔开。

至于只在makefile文件中出现的变量,则会全部以小写来编写其名称,单词之间以下划线符号隔开。最后,内含用户自定义

函数的变量以及宏都会以小写来编写其名称,单词之间以破折号-隔开。

#常数

CC := gcc

MKDIR := mkdir -p


#内部变量

sources = *.c

objects = $(subst .c,.o,$(sources))


#函数

maybe-make-dir = $(if $(wildcard $1),,$(MKDIR) $1)


1.变量的类型

make的变量有两种类型:经简单扩展的变量以及经递归扩展的变量

你可以使用:=赋值运算来定义一个经简单扩展的变量:

MAKE_DEPEND := $(CC) -M

之所以称此变量为经简单扩展时因为,一旦make从makefile读进该变量的定义语句,赋值运算符的右边部分会立即被扩展。

赋值运算符的右边部分只要出现make变量的引用就会被扩展,而扩展后所产生的文本则会被存储称该变量的值。此行为跟

大多数的程序和脚本语言相同。举例,此变量被扩展之后一般会成为下面这样:

gcc -M

然而,如果上面的CC变量尚未定义,则此变量被扩展后一般会变成这样:

<space> -M


第二种变量类型称为经递归扩展的变量。你可以用=赋值运算符来定义一个经递归扩展的变量:

MAKE_DEPEND = $(CC) -M

之所以称此变量为经递归扩展是因为,make只会读进赋值运算符右边的部分,并将之存储成该变量的值,但不会进行任何

扩展的动作,扩展动作会被延迟到该变量被使用的时候才进行,将此变量称为延后扩展的变量或许比较恰当。因为扩展动作

会延迟到该变量实际被使用的时候才进行。

MAKE_DEPEND = $(CC) -M

...

#稍后

CC = gcc

这样,当MAKE_DEPEND被使用的使用,即使CC并未定义,MAKE_DEPEND在脚本中的值也会被扩展成gcc -M。


2.其他的赋值类型

make还另外提供了两种赋值运算符:?= 和 +=。

?= 运算符称为附带条件的变量赋值运算符。此运算符只会在变量的值尚不存在的状况下进行变量要求赋值的动作。

#将所产生的每个文件放到$(PROJECT_DIR)/out目录中。

OUTPUT_DIR ?= $(PROJECT_DIR)/out

我们只会在输出目录变量OUTPUT_DIR的值尚不存在的状况下对它进行赋值的动作。


+=运算符通常被称为附件运算符,此运算符会将文本附加到变量中,对于简单变量进行附加的动作,+=运算符可以被实现

成这样:

simple := $(simple) new stuff

但是递归变量会导致一个问题,如果将+=运算符实现成下面这样,是不允许的。

recursive = $(recursive) new stuff

这时一个错误,因为make没有办法妥善地加以处理。如果make存储recursive当前的定义加上new stuff,则make就不能在

运行时再次扩展它。此时试图扩展一个自我引用的递归变量将会产生一个无限循环。

所以,+=被特别实现成可将文本附加到递归变量中并做正确的事。


3.宏

变量适合用来存储单行形式的值,对于多行形式的值,例如命令脚本,如果我们想在不同的地方执行它,该怎么办?例如

下面的命令序列:

ehco create $@...

$(RM) $(TMP_DIR)

$(MKDIR) $(TMP_DIR)

$(CC) main.c

$(RM) $(TMP_DIR)

在GNU make中,我们可以通过define指令以创建宏,在make中,宏只是用来定义变量的另一种方式,此变量还可以包含

内置换行符号。

define create-obj

  @echo create $@...

  $(RM) $(TMP_DIR)

  $(MKDIR) $(TMP_DIR)

  $(CC) main.c

  $(RM) $(TMP_DIR)

endef

define指令后面跟着变量名称以及一个换行符号。变量的主体包含了所有的命令序列直到endef关键字出现为止,endef关键字

必须自成一行。一个由define创建的变量,就像任何其他的边来个你一样,会被扩展许多次,除非它被使用在命令脚本的语境

中,下面是宏的使用范例:

$(UI-OBJ):$(UI-CLASSES)

        $(create-obj)

请注意,我们为echo命令前置了一个@字符,当执行命令脚本时,前置@字符的命令行不会被make输出,因此,当我们运行

make时,它不会输出echo命令本身,只会输出该命令的输出,如果在宏内部使用@前缀,这个前缀字符只会影响使用到它的

命令行。然而,如果将这个前缀用在宏引用上,则整个宏主体都会被隐藏起来:

$(UI-OBJ):$(UI-CLASSES)

        @$(create-obj)

当make运行时只会显示:

$make

create ui-obj...

文章评论

为什么程序员都是夜猫子
为什么程序员都是夜猫子
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
总结2014中国互联网十大段子
总结2014中国互联网十大段子
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
Java程序员必看电影
Java程序员必看电影
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
鲜为人知的编程真相
鲜为人知的编程真相
我的丈夫是个程序员
我的丈夫是个程序员
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
一个程序员的时间管理
一个程序员的时间管理
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
我是如何打败拖延症的
我是如何打败拖延症的
老程序员的下场
老程序员的下场
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
程序员必看的十大电影
程序员必看的十大电影
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
10个调试和排错的小建议
10个调试和排错的小建议
每天工作4小时的程序员
每天工作4小时的程序员
程序员都该阅读的书
程序员都该阅读的书
编程语言是女人
编程语言是女人
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
那些争议最大的编程观点
那些争议最大的编程观点
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
如何成为一名黑客
如何成为一名黑客
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
程序员的鄙视链
程序员的鄙视链
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
 程序员的样子
程序员的样子
代码女神横空出世
代码女神横空出世
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
程序员应该关注的一些事儿
程序员应该关注的一些事儿
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
旅行,写作,编程
旅行,写作,编程
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有