makefile进阶(一)--目标target

本文深入讲解Makefile的基础概念与实际应用技巧,包括如何定义目标文件、依赖文件及伪目标,同时还介绍了make的自动推导机制、静态模式的使用方法等高级特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文由导学宝转自:http://blog.chinaunix.net/uid-26822401-id-3158091.html
(首先声明,本文摘自《跟我一起写 Makefile》作者陈皓 (优快云),他的MSN是: haoel@hotmail.com。我后面三章基本是直接拷过来的,前面的倒是按照自己的理解码的,例子和解释会有不同。)


一般来说,一个target是一个要生成的文件,它会有一个或多个依赖的目标。比如:
foo.o: foo.c
表示要生成的文件为foo.o,而依赖的文件是foo.c。make会自动为我们执行类似于cc foo.c -o foo.o的命令。

这里make在每次运行时会比较依赖文件与目标文件的更新时间,如果foo.c比foo.o更新,那么说明foo.c在上次编译后改动过,所以foo.o会再次编译;否则make假定foo.o已经是最新,不再编译。

对于头文件,我们也应该把它加入到依赖目标集里。就像:
foo.o: foo.c foo.h
这是因为如果不加入头文件的依赖,那么在上次编译后即使foo.h有改动,make也认为foo.o为最新。


make的自动推导可以为目标指定相应的源文件作为依赖目标。
比如makefile这么写:
foo.o:
会等同于
foo.o: foo.c

make它的话,会有如下结果:
$ make foo.o
cc    -c -o foo.o foo.c


对于不是文件的目标,我们称之为伪目标,比如clean:,它只是一个标签。我们可以用.PHONY来显式地声明一个目标是伪目标,这样不管是否存在这个文件,目标都被视为是伪目标。比如:
.PHONY: clean
clean:
    rm *.o

同样,一旦我们声明
PHONY:foo.o,
那么foo.o就不会被生成。

有一点要注意的是,make会检查文件目标的更新时间,如果已有的目标文件比源文件新,那么这个目标就不会执行;但是伪目标总是会执行。


我们可以同时指定多个目标,来执行相同的命令,变量$@指定当前的目标名。比如:
tOne tTwo: foo2.o foo3.o
    echo $@

make命令会生成:
$ make tOne
cc    -c -o foo2.o src1/foo2.c
cc    -c -o foo3.o src2/foo3.c
echo tOne
tOne

多个目标其实会被展开,上面的例子其实等价于:
tOne: foo2.o foo3.o
    echo $@
tTwo: foo2.o foo3.o
    echo $@


我们可以使用静态模式来从根据目标来指定依赖的目标集。静态模式的语法为:
<targets ...>: <target-pattern>:<prereq-patterns...>

先举个例子:
OBJECTS=foo1.o foo2.o
all: foo1.o foo2.o
$(OBJECTS):%.o:src1/%.c
    $(CC) -c -o $@ "$<" 

这 里<targets...>是foo1.o和foo2.o;<target-pattern>是%.o;<prereq- patterns...>为src1/%c。两个pattern中的“%”是必需的。静态模式就是需要从所有targets中抽取匹配“%”的部 分,再由这个部分生成信赖目标集。如之前所说的,$@是目标名,而$<是依赖目标集名。

上面的静态模式展开后等价于:
$foo1.o:src1/foo1.c
    $(CC) -c -o foo1.o "src1/foo1.c" 
$foo1.o:src2/foo2.c
    $(CC) -c -o foo2.o "src1/foo2.c"

再举个例子来加深对静态模式的理解:
tall: tAx tBx tCx

tAx tBx tCx:t%x:%1 %2 %3

A1 A2 A3:
    echo $@
B1 B2 B3:
    echo $@
C1 C2 C3:
    echo $@

make产生的结果为:

$ make tall
echo A1
A1
echo A2
A2
echo A3
A3
echo B1
B1
echo B2
B2
echo B3
B3
echo C1
C1
echo C2
C2
echo C3
C3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值