makefile(三):隐含规则

一.隐含规则

上面介绍的全是显式规则,下面叙述隐含规则。隐含规则是make内置的规则,这些规则通常为一些常见的规则,比如c文件的编译,库文件的编译。这样可以减少makefile文件内容的编写。
举例如下。
在src目录下存在一个test.c文件。此时不用编写任何makefile文件,直接运行make test,那么此时,会生成对应的test可执行文件。
此时make在执行的时候,发现test可以由test.c生成,因此,使用了工作目录下的test.c来生成test目标,而生成test目标的命令,已经被内置在了make里面。
make还内置了很多这种类型的规则,常见的有:
1. 编译C 程序
2. 编译C++ 程序
3. 编译Pascal 程序
4. 编译Fortran/Ratfor 程序
5. 预处理Fortran/Ratfor 程序
6. 编译Modula-2 程序
7. 汇编和需要预处理的汇编程序
8. 链接单一的object 文件
9. Yacc C 程序
10. Lex C程序
等等…
什么时候make会去调用隐含规则?
当所有需要的目标,或者依赖文件,没有被明确的规则定义的时候,make会去使用相应的隐含规则来实现。
make为了便于修改隐含规则,给隐含规则里面的命令做了对应的变量,例如对于c文件的编译。定义了如下两个变量,$(CC)和$(CFLAGS),前者表示使用的命令,后者表示使用的参数。CC变量默认使用的是shell里面的cc变量,我们可以给CC变量指定其他的值,来更改编译器,这样就能更改隐含规则中的命令。同样的命令变量还有如下:

AR 函数库打包程序,可创建静态库.a文档。默认是“ar” 。
AS 汇编程序。默认是“as” 。
CC C编译程序。默认是“cc” 。
CXX C++编译程序。默认是“g++” 。
CO 从 RCS中提取文件的程序。默认是“co” 。
CPP C程序的预处理器(输出是标准输出设备) 。默认是“$(CC) –E” 。
FC 编译器和预处理Fortran 和 Ratfor 源文件的编译器。默认是“f77” 。
GET 从SCCS中提取文件程序。默认是“get” 。
LEX 将 Lex 语言转变为 C 或 Ratfo 的程序。默认是“lex” 。
PC Pascal语言编译器。默认是“pc” 。
YACC Yacc文法分析器(针对于C程序) 。默认命令是“yacc” 。
YACCR Yacc文法分析器(针对于Ratfor程序) 。默认是“yacc –r” 。
MAKEINFO 转换Texinfo源文件(.texi)到Info文件程序。默认是“makeinfo” 。
TEX 从TeX源文件创建TeX DVI文件的程序。默认是“tex” 。
TEXI2DVI 从Texinfo源文件创建TeX DVI 文件的程序。默认是“texi2dvi” 。
WEAVE 转换Web到TeX的程序。默认是“weave” 。
CWEAVE 转换C Web 到 TeX的程序。默认是“cweave” 。
TANGLE 转换Web到Pascal语言的程序。默认是“tangle” 。
CTANGLE 转换C Web 到 C。默认是“ctangle” 。
RM 删除命令。默认是“rm –f” 。

同样相应的参数变量也有下面:

ARFLAGS 执行“AR”命令的命令行参数。默认值是“rv” 。
ASFLAGS 执行汇编语器“AS”的命令行参数(明确指定“.s”或“.S”文件时) 。
CFLAGS 执行“CC”编译器的命令行参数(编译.c源文件的选项) 。
CXXFLAGS 执行“g++”编译器的命令行参数(编译.cc源文件的选项) 。
COFLAGS 执行“co”的命令行参数(在RCS中提取文件的选项) 。
CPPFLAGS 执行C预处理器“cc -E”的命令行参数(C 和 Fortran 编译器会用到) 。
FFLAGS   Fortran语言编译器“f77”执行的命令行参数(编译Fortran源文件的选项) 。
GFLAGS  SCCS “get”程序参数。
LDFLAGS 链接器参数。 (如: “ld” )
LFLAGS Lex文法分析器参数。
PFLAGS  Pascal语言编译器参数。
RFLAGS  Ratfor 程序的Fortran 编译器参数。
YFLAGS  Yacc文法分析器参数。

给隐含规则添加依赖
在使用的途中,往往需要给隐含规则添加一些依赖。可以直接在目标后面添加依赖即可,不需要命令行。如下:

foo.o:definsh.h

当使用隐含规则来创建foo.o时,会将definsh.h依赖加入依赖列表中
重建隐含规则
在使用的时候,我们不希望使用内置的隐含规则,此时可以重建内嵌的隐含规则,方法有两两种,一种是:使用模式规则,另外一种是:使用后缀规则。
1.使用模式规则进行替换。
此时需要具有相同的目标和相同的依赖,然后使用不同的命令。如下:

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

这个模式规则就替换了隐含规则。
当没有命令行时,表示取消内置的隐含规则。
2.使用后缀规则
这个是在老版本的makefile中使用的一种语法。新版本的makefile推荐使用模式规则。语法如下:

依赖后缀目标后缀:
        命令

例子如下:

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

后缀规则不能拥有依赖,如下:

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

此时他不是一个后缀规则,他表示的是:目标为.c.o,依赖为foo.h
为了将一个目标强制定义为后缀规则,可以使用内置.SUFFIXES目标。如下

.SUFFIXES:.win .biao

它表示:将.win和.biao加入到可识别的后缀列表中。
单独使用.SUFFIXES表示取消所有已经定义的可识别后缀。

二.万用规则

当模式规则的目标为%的时候,称为万用规则。他能够匹配所有的文件,这个非常有用,但是却非常的影响效率,因为make里面的所有目标和依赖都会去考虑使用万用规则。
避免这种情况有两种方法:
1.使用最终规则,定义的时候使用双冒号规则。
此规则只有在依赖文件存在的时候,才会被应用。当依赖文件不存在时,不会考虑在使用万用规则。如下:

% :: RCS/%,v

表示任何一个文件,可以从RCS文件夹下对应的,v文件中提取出来,当RCS下面没有对应的文件时,这个规则无效。
2.特殊的内嵌伪模式
用来指定一些特定的文件,避免处理这些文件的时候使用了非最终的万用规则(即没有包含双冒号的万用规则)。他们没有依赖和命令行。如下:

%.p:

保证在.p文件不会被用在非最终的万用规则上。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值