makefile

http://www.cnblogs.com/liyanwei/archive/2010/04/29/1723931.html

$@
表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,"$@"就是匹配于目标中模式定义的集合。就像一个数组,“$@”依次取出目标,并执于命令。

$%
仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是"foo.a(bar.o)",那么,"$%"就是"bar.o","$@"就是"foo.a"。如果目标不是函数库文件(Unix下是[.a],Windows下是[.lib]),那么,其值为空。

$<
依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。注意,其是一个一个取出来的。

$?
所有比目标新的依赖目标的集合。以空格分隔。

$^
所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会
去除重复的依赖目标,只保留一份。

$+
这个变量很像"$^",也是所有依赖目标的集合。只是它不去除重复的依赖目标。

$*
这个变量表示目标模式中"%"及其之前的部分。如果目标是"dir/a.foo.b",并且目标的模
式是"a.%.b",那么,"$*"的值就是"dir /a.foo"。这个变量对于构造有关联的文件名是比
较有较。如果目标中没有模式的定义,那么"$*"也就不能被推导出,但是,如果目标文件
的后缀是 make所识别的,那么"$*"就是除了后缀的那一部分。例如:如果目标是"foo.c"
,因为".c"是make所能识别的后缀名,所以,"$*"的值就是"foo"。这个特性是GNU make的
,很有可能不兼容于其它版本的make,所以,你应该尽量避免使用"$*",除非是在隐含规
则或是静态模式中。如果目标中的后缀是make所不能识别的,那么"$*"就是空值。

当你希望只对更新过的依赖文件进行操作时,"$?"在显式规则中很有用,例如,假设有一
个函数库文件叫"lib",其由其它几个object文件更新。那么把object文件打包的比较有效
率的Makefile规则是:

lib : foo.o bar.o lose.o win.o
ar r lib $?

 

自动化变量

$@,这个变量表示着目前规则中所有的目标的集合

“$<”表示所有的依赖目标集,“$@”表示目标集
)。

bigoutput littleoutput : text.g
    generate text.g -$(subst output,,$@) > $@

上述规则等价于:
bigoutput : text.g
    generate text.g -big > bigoutput
littleoutput : text.g
    generate text.g -little > littleoutput
其中,-$(subst output,,$@)中的“$”表示执行一个Makefile的函数,函数名为subst,
后面的为参数。截取字符串的意思,“$@”,表示目标的集合,就像一个数组,“$@”依次取出目标,并执于命令。

 

静态模式

<targets ...>: <target-pattern>: <prereq-patterns ...>
<commands>
...

targets定义了一系列的目标文件,可以有通配符。是目标的一个集合。
target-parrtern是指明了targets的模式,也就是的目标集模式。为了说明targets
prereq-parrterns是目标的依赖模式,它对target-parrtern形成的模式再进行一次依赖目
标的定义。

objects = foo.o bar.o
all: $(objects)

$(objects): %.o: %.c
    $(CC) -c $(CFLAGS) $< -o $@

“$<”表示所有的依赖目标集(也就是“foo.c bar.c”),“$@”表示目标集(也就是“foo.o bar.o”)。

上面的规则展开后等价于下面的规则:
foo.o : foo.c
    $(CC) -c $(CFLAGS) foo.c -o foo.o
bar.o : bar.c
    $(CC) -c $(CFLAGS) bar.c -o bar.o


伪目标

clean:
rm *.o temp

我们并不生成“clean”这个文件。由于“伪目标”不是文件,所以make无法生成它的依赖关系和决定它是否要执行。我们只有
通过显示地指明这个“目标”才能让其生效。当然,“伪目标”的取名不能和文件名重名,不然其就失去了“伪目标”的意义了。
all也可以定义为伪目标,Makefile中的第一个目标会被作为其默认目标。我们声明了一个“all”的伪目
标,其依赖于其它三个目标。


当然,为了避免和文件重名的这种情况,我们可以使用一个特殊的标记“.PHONY”来显示
地指明一个目标是“伪目标”,向make说明,不管是否有这个文件,这个目标就是“伪目
标”。


.PHONY : clean


自动推导

只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。并且 cc -c whatever.c 

例如:

objects = main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o

edit : $(objects)
cc -o edit $(objects)

main.o : defs.h
kbd.o : defs.h command.h

.PHONY : clean
clean :
rm edit $(objects)

显示命令

@echo 正在编译XXX模块......


命令出错

clean:
-rm -f *.o

rm前加-表示文件不存在时,依然进行


嵌套执行make

subsystem:            #子目录
cd subdir && $(MAKE)

 

如果要传递变量到下级Makefile中,那么可以使用这样的声明:
export <variable ...>


变量

变量在声明时需要给予初值,而在使用时,需要给在变量名前加上“$”符号,但最好用小括号“()”或是大括号“{}”把变量给包括起来。如果你要使用真实的“$”字符,那么你需要用“$$”来表示。


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


x := later
这种赋值方法,前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。


objects = main.o foo.o bar.o utils.o
objects += another.o
“+=”操作符给变量追加值


模式规则

%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

表示把所有的[.c]文件都编译成[.o]文件,其中,"$@"表示所有的目标的挨个值,"$<"表示了所有依赖目标的挨个值。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值