<!---->
<o:p>
</o:p>
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2895
四、
foreach
函数
<o:p> </o:p>
foreach
函数和别的函数非常的不一样。因为这个函数是用来做循环用的,
Makefile
中的
foreach
函数几乎是仿照于
Unix
标准
Shell
(
/bin/sh
)中的
for
语句,或是
C-Shell
(
/bin/csh
)中的
foreach
语句而构建的。它的语法是:
<o:p>
</o:p>
<o:p> </o:p>
$(foreach <var>,<list>,<text>)<o:p></o:p>
<o:p> </o:p>
这个函数的意思是,把参数
<list>
中的单词逐一取出放到参数
<var>
所指定的变量中,然后再执行
<text>
所包含的表达式。每一次
<text>
会返回一个字符串,循环过程中,
<text>
的所返回的每个字符串会以空格分隔,最后当整个循环结束时,
<text>
所返回的每个字符串所组成的整个字符串(以空格分隔)将会是
foreach
函数的返回值。
<o:p>
</o:p>
<o:p> </o:p>
所以,
<var>
最好是一个变量名,
<list>
可以是一个表达式,而
<text>
中一般会使用
<var>
这个参数来依次枚举
<list>
中的单词。举个例子:
<o:p>
</o:p>
<o:p> </o:p>
names := a b c d<o:p></o:p>
files := $(foreach n,$(names),$(n).o)<o:p></o:p>
<o:p> </o:p>
上面的例子中,
$(name)
中的单词会被挨个取出,并存到变量“
n
”中,“
$(n).o
”每次根据“
$(n)
”计算出一个值,这些值以空格分隔,最后作为
foreach
函数的返回,所以,
$(files)
的值是“
a.o b.o c.o d.o
”。
<o:p>
</o:p>
<o:p> </o:p>
注意,
foreach
中的
<var>
参数是一个临时的局部变量,
foreach
函数执行完后,参数
<var>
的变量将不在作用,其作用域只在
foreach
函数当中。
<o:p>
</o:p>
<o:p> </o:p>
<o:p> </o:p>
五、
if
函数
<o:p> </o:p>
if
函数很像
GNU
的
make
所支持的条件语句——
ifeq
(参见前面所述的章节),
if
函数的语法是:
<o:p>
</o:p>
<o:p> </o:p>
$(if <condition>,<then-part>) <o:p></o:p>
<o:p> </o:p>
或是
<o:p>
</o:p>
<o:p> </o:p>
$(if <condition>,<then-part>,<else-part>)<o:p></o:p>
<o:p> </o:p>
可见,
if
函数可以包含“
else
”部分,或是不含。即
if
函数的参数可以是两个,也可以是三个。
<condition>
参数是
if
的表达式,如果其返回的为非空字符串,那么这个表达式就相当于返回真,于是,
<then-part>
会被计算,否则
<else-part>
会被计算。
<o:p>
</o:p>
<o:p> </o:p>
而
if
函数的返回值是,如果
<condition>
为真(非空字符串),那个
<then-part>
会是整个函数的返回值,如果
<condition>
为假(空字符串),那么
<else-part>
会是整个函数的返回值,此时如果
<else-part>
没有被定义,那么,整个函数返回空字串。
<o:p>
</o:p>
<o:p> </o:p>
所以,
<then-part>
和
<else-part>
只会有一个被计算。
<o:p>
</o:p>
<o:p> </o:p>
<o:p> </o:p>
六、
call
函数
<o:p> </o:p>
call
函数是唯一一个可以用来创建新的参数化的函数。你可以写一个非常复杂的表达式,这个表达式中,你可以定义许多参数,然后你可以用
call
函数来向这个表达式传递参数。其语法是:
<o:p>
</o:p>
<o:p> </o:p>
$(call <expression>,<parm1>,<parm2>,<parm3>...)<o:p></o:p>
<o:p> </o:p>
当
make
执行这个函数时,
<expression>
参数中的变量,如
$(1)
,
$(2)
,
$(3)
等,会被参数
<parm1>
,
<parm2>
,
<parm3>
依次取代。而
<expression>
的返回值就是
call
函数的返回值。例如:
reverse = $(1) $(2)<o:p></o:p>
foo = $(call reverse,a,b)
<o:p></o:p>
那么,
foo
的值就是“
a b
”。当然,参数的次序是可以自定义的,不一定是顺序的,如:
<o:p>
</o:p>
<o:p> </o:p>
reverse = $(2) $(1)<o:p></o:p>
foo = $(call reverse,a,b)
<o:p></o:p>
此时的
foo
的值就是“
b a
”。
<o:p>
</o:p>
<o:p> </o:p>
<o:p> </o:p>
七、
origin
函数
<o:p>
</o:p>
origin
函数不像其它的函数,他并不操作变量的值,他只是告诉你你的这个变量是哪里来的?其语法是:
<o:p>
</o:p>
<o:p> </o:p>
$(origin <variable>)<o:p></o:p>
<o:p> </o:p>
注意,
<variable>
是变量的名字,不应该是引用。所以你最好不要在
<variable>
中使用“
$
”字符。
Origin
函数会以其返回值来告诉你这个变量的“出生情况”,下面,是
origin
函数的返回值
:<o:p></o:p>
<o:p> </o:p>
“
undefined
”
<o:p>
</o:p>
如果
<variable>
从来没有定义过,
origin
函数返回这个值“
undefined
”。
<o:p>
</o:p>
<o:p> </o:p>
“
default
”
<o:p>
</o:p>
如果
<variable>
是一个默认的定义,比如“
CC
”这个变量,这种变量我们将在后面讲述。
<o:p>
</o:p>
<o:p> </o:p>
“
environment
”
<o:p>
</o:p>
如果
<variable>
是一个环境变量,并且当
Makefile
被执行时,“
-e
”参数没有被打开。
<o:p>
</o:p>
<o:p> </o:p>
“
file
”
<o:p>
</o:p>
如果
<variable>
这个变量被定义在
Makefile
中。
<o:p>
</o:p>
<o:p> </o:p>
“
command line
”
<o:p>
</o:p>
如果
<variable>
这个变量是被命令行定义的。
<o:p>
</o:p>
<o:p> </o:p>
“
override
”
<o:p>
</o:p>
如果
<variable>
是被
override
指示符重新定义的。
<o:p>
</o:p>
<o:p> </o:p>
“
automatic
”
<o:p>
</o:p>
如果
<variable>
是一个命令运行中的自动化变量。关于自动化变量将在后面讲述。
<o:p>
</o:p>
<o:p> </o:p>
这些信息对于我们编写
Makefile
是非常有用的,例如,假设我们有一个
Makefile
其包了一个定义文件
Make.def
,在
Make.def
中定义了一个变量“
bletch
”,而我们的环境中也有一个环境变量“
bletch
”,此时,我们想判断一下,如果变量来源于环境,那么我们就把之重定义了,如果来源于
Make.def
或是命令行等非环境的,那么我们就不重新定义它。于是,在我们的
Makefile
中,我们可以这样写:
<o:p>
</o:p>
<o:p> </o:p>
ifdef bletch<o:p></o:p>
ifeq "$(origin bletch)" "environment"<o:p></o:p>
bletch = barf, gag, etc.<o:p></o:p>
endif<o:p></o:p>
endif<o:p></o:p>
<o:p> </o:p>
当然,你也许会说,使用
override
关键字不就可以重新定义环境中的变量了吗?为什么需要使用这样的步骤?是的,我们用
override
是可以达到这样的效果,可是
override
过于粗暴,它同时会把从命令行定义的变量也覆盖了,而我们只想重新定义环境传来的,而不想重新定义命令行传来的。
<o:p>
</o:p>
<o:p> </o:p>
<o:p> </o:p>
八、
shell
函数
<o:p> </o:p>
shell
函数也不像其它的函数。顾名思义,它的参数应该就是操作系统
Shell
的命令。它和反引号“
`
”是相同的功能。这就是说,
shell
函数把执行操作系统命令后的输出作为函数返回。于是,我们可以用操作系统命令以及字符串处理命令
awk
,
sed
等等命令来生成一个变量,如:
<o:p>
</o:p>
<o:p> </o:p>
contents := $(shell cat foo)<o:p></o:p>
<o:p> </o:p>
files := $(shell echo *.c)<o:p></o:p>
<o:p> </o:p>
注意,这个函数会新生成一个
Shell
程序来执行命令,所以你要注意其运行性能,如果你的
Makefile
中有一些比较复杂的规则,并大量使用了这个函数,那么对于你的系统性能是有害的。特别是
Makefile
的隐晦的规则可能会让你的
shell
函数执行的次数比你想像的多得多。
<o:p>
</o:p>
<o:p> </o:p>
<o:p> </o:p>
九、控制
make
的函数
<o:p> </o:p>
make
提供了一些函数来控制
make
的运行。通常,你需要检测一些运行
Makefile
时的运行时信息,并且根据这些信息来决定,你是让
make
继续执行,还是停止。
<o:p>
</o:p>
<o:p> </o:p>
$(error <text ...>)<o:p></o:p>
<o:p> </o:p>
产生一个致命的错误,
<text ...>
是错误信息。注意,
error
函数不会在一被使用就会产生错误信息,所以如果你把其定义在某个变量中,并在后续的脚本中使用这个变量,那么也是可以的。例如:
<o:p>
</o:p>
<o:p> </o:p>
示例一:
<o:p>
</o:p>
ifdef ERROR_001<o:p></o:p>
$(error error is $(ERROR_001))<o:p></o:p>
endif<o:p></o:p>
<o:p> </o:p>
示例二:
<o:p>
</o:p>
ERR = $(error found an error!)<o:p></o:p>
.PHONY: err<o:p></o:p>
err: ; $(ERR)<o:p></o:p>
<o:p> </o:p>
示例一会在变量
ERROR_001
定义了后执行时产生
error
调用,而示例二则在目录
err
被执行时才发生
error
调用。
<o:p>
</o:p>
<o:p> </o:p>
$(warning <text ...>)<o:p></o:p>
<o:p> </o:p>
相关推荐
跟我一起写Makefile跟我一起写Makefile跟我一起写Makefile跟我一起写Makefile跟我一起写Makefile跟我一起写Makefile跟我一起写Makefile跟我一起写Makefile跟我一起写Makefile跟我一起写Makefile跟我一起写Makefile跟...
《跟我一起写Makefile》是陈皓所著的一本深入探讨Makefile编写的书籍,由祝冬华整理,全文共计78页,于2005年10月14日发布。本书全面覆盖了Makefile的基础知识到高级应用,旨在帮助读者掌握如何有效地编写Makefile,...
《跟我一起写Makefile》是陈皓大佬撰写的一份PDF文档,主要讲解了如何编写和理解Makefile,以便于管理程序的编译和链接过程。Makefile是软件开发中的一个重要工具,它帮助自动化构建过程,使得编译和链接更加高效。 ...
Makefile编译和链接基础知识 Makefile是 Unix 和 Unix-like 操作系统中一种工具,用于自动编译和链接程序。Makefile 文件中包含了一系列规则,指定了编译和链接的过程。下面将详细介绍 Makefile 的基本概念和使用...
make是一个命令工具,它解释Makefile 中的指令(应该说是规则)。在Makefile文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile 有自己的书写格式、关键字、函数。像C 语言有自己的格式、关键字和函数一样...
《跟我一起写 Makefile》由陈皓撰写,祝冬华整理,是一份深入讲解Makefile的教程。Makefile是Linux环境中用于自动化构建、编译和链接程序的重要工具,它通过简洁的规则定义来管理复杂的项目构建过程。以下是该文档...
### 跟我一起写Makefile (PDF重制版) #### 概述 《跟我一起写Makefile (PDF重制版)》是一本详细介绍如何编写Makefile的指南书,适用于希望深入了解并掌握Makefile编写的程序员。Makefile是用于自动化构建过程的一...
Makefile 跟我一起写Makefile;Makefile 跟我一起写Makefile;Makefile 跟我一起写Makefile
《跟我一起写 Makefile》是由陈皓编著的一本关于Makefile使用的指南,旨在帮助读者理解和掌握这个在软件开发中至关重要的工具。Makefile是Unix和类Unix系统中用于自动化构建、编译和测试程序的文件,它定义了一系列...
实际上很多接触编程很长时间的人 并不会写MAKEFILE,所以跟我来写MAKEFILE 用ULTRAEDIT来打开。WORD是打不开的
### 跟我一起写Makefile #### 一、Makefile简介 Makefile是一种用于自动化构建过程的脚本文件,广泛应用于软件项目管理和自动化构建领域。对于任何希望提高开发效率和减少手动构建工作量的开发者来说,理解...
跟我一起写 Makefile 在软件开发中,Makefile 是一种非常重要的工具,它帮助开发者自动化构建、编译和链接过程,提高工作效率。本教程将深入探讨 Makefile 的使用方法和核心概念。 1. 概述 Makefile 是一个文本...