makefile(三):隐含规则
2017-10-18 16:04
253 查看
一.隐含规则
上面介绍的全是显式规则,下面叙述隐含规则。隐含规则是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文件不会被用在非最终的万用规则上。
相关文章推荐
- Makefile十七之后缀规则和隐含规则的搜索算法
- Makefile隐含规则
- Makefile‘混和的隐含和普通规则’错误的解决
- makefile文件详解--隐含规则
- Makefile--隐含规则自动推dao(一)
- Makefile‘混和的隐含和普通规则’错误的解决
- Makefile讲义(9)——隐含规则
- makefile 隐含规则
- linux下Makefile的学习之八(隐含规则)
- Makefile之隐含规则
- Makefile‘ *** 混和的隐含和普通规则’错误的解决
- Makefile (八)之 隐含规则
- Makefile中使用隐含规则来编译程序
- 对busybox使用make menuconfig出现错误“makefile 混和的隐含和普通规则。停止。”
- “Makefile:xxx:***混合的隐含和普通规则。停止”
- 跟我一起写 Makefile——1.11 隐含规则
- gcc -M 选项 以及Makefile隐含规则
- makefile高级用法--隐含规则
- makefile 隐含规则
- Makefile学习之隐含规则(一)