ILD

Make学习:Using Implicit Rules
作者:Yuan Jianpeng 邮箱:yuanjp89@163.com
发布时间:2019-5-25 站点:Inside Linux Development

10.1 Using Implicit Rules

foo : foo.o bar.o

    cc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)


可能有多个隐藏规则,foo.o bar.o会应用隐藏规则,如果有foo.c bar.c,则应用编译c的隐藏规则。


你可以写一个没有recipe的rule,添加依赖,这不影响应用隐藏规则,同时可以添加自己的依赖,比如:

foo.o: foo.h


通常,make在每个没有recipe的target,double-colon rule,上搜索隐藏规则。


如果一个文件只在依赖中提到,那么被认为是一个没有rule的target,也会应用隐藏规则。


如果你不想implicit rule应用到target,那么可以写一个empty recipe,用分号:

target: ;


10.2 Catalogue of Built-In Rules

可以通过命令行选项取消隐藏规则:-r 或者 --no-builtin-rules


可以再没有makefile的目录执行,make -p ,来查看所有的隐藏规则。


10.3 Variables Used by Implicit Rules

内置隐藏规则recipe试用predefined variables,比如CC变量是cc。


使用-R或者--no-bultin-variables,来取消所有隐藏规则使用的变量。


预定义变量分为两类,第一类是编译的程序,比如CC。第二类是参数CFLAGS


10.5 Defining and Redefining Pattern Rules

一个pattern rule包含%,prerequisite也可以包含%,它是target中%匹配的部分。

%.o : %.c


10.5.3 Automatic Variables

$@ 目标的名字

$< 第一个依赖

$? 比target新的所有依赖

$^ 所有依赖,不包括order-only依赖。

$| 所有的order-only 依赖,


$* 

对于pattern rule,是%匹配的部分。

对于explicit rule,是除去后缀的部分。

1
2
3
4
5
6
7
8
9
10
11
$ cat Makefile 
 
a.c:
    @echo $*
 
%.o:
    @echo $*
$ make a.c
a
$ make a.o
a


10.5.4 How Patterns Match

%匹配的部分叫做stem。


当target pattern不包含斜杠时,文件名中的目录被移除,只匹配文件,但是依赖则会加上去。

%.o: %.c

如果编译src/a.o,那么依赖是src/a.c


A pattern rule can be used to build a given file only if there is a target pattern that matches the file name, and all prerequisites in that rule either exist or can be built

只有当目标和依赖同时满足时,pattern rule才会匹配。


可以有多个目标相同的pattern rule,但是依赖不同,make会优先匹配依赖存在的rule,或者stem最短的rule。

%.o: %.c

    $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

%.o : %.f

    $(COMPILE.F) $(OUTPUT_OPTION) $<

lib/%.o: lib/%.c

    $(CC) -fPIC -c $(CFLAGS) $(CPPFLAGS) $< -o $@


编译bar.o,如果存在bar.c则使用第一条rule。


10.5.5 Match-Anything Pattern Rules

%,通常要定义成双冒号,即双冒号的话,rule是terminal rule,


non terminal match-anything pattern rule不能匹配那些能匹配pattern rule但是依赖不存在的目标。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ cat Makefile 
 
%.o: %.c
    echo %.o
 
%:
    @echo %: $@
$ make x.o
make: *** No rule to make target 'x.o'.  Stop.
 
$ cat Makefile 
 
%.o: %.c
    echo %.o
 
%::
    @echo %: $@
$ make x.o
%: x.o

如上,如果是%:,则不能匹配x.o,因为x.o匹配了%.o,且x.c不存在,如果定义成双冒号,则可以匹配。


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.