详细内容见 《GNU make》 10 Using Implicit Rules 章节。
某些重制目标文件的标准方法经常被使用。例如,创建目标文件的一种习惯方法是使用 C 编译器 cc 从 C 源文件中获取目标文件。
隐式规则告诉 A 如何使用习惯技巧,这样当你想要使用它们时,就不必详细地指定它们。例如,有一个用于C编译的隐式规则。文件名确定运行哪些隐式规则。例如,C编译通常接受 .c 文件并生成 .o 文件。因此,当 make 看到这个文件名结尾的组合时,它应用了 C 编译的隐式规则。
一系列隐式规则可以按顺序应用;例如,make 将通过 .c 文件从 .y 文件重制 .o 文件。
内置隐式规则在其配方中使用多个变量,因此,通过更改变量的值,您可以更改隐式规则的工作方式。例如,变量 CFLAGS 通过 C 编译的隐式规则控制给 C 编译器的标志。
您可以通过编写模式规则来定义自己的隐式规则。
后缀规则是定义隐式规则的一种更有限的方式。模式规则更加通用和清晰,但是后缀规则为了兼容性而保留。
一、用隐式规则
要让 make 找到更新目标文件的习惯方法,您所要做的就是避免自己指定配方。要么写一个没有配方的规则,要么根本不写规则。然后 make 会根据存在或可以创建的源文件类型,找出使用哪种隐式规则。
例如,假设makefile是这样的:
foo : foo.o bar.o
cc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)
因为你提到了 foo.o 但没有给它一个规则,make 将自动寻找一个隐式规则来告诉如何更新它。无论文件 foo.o 当前是否存在,都会发生这种情况。
如果找到隐式规则,它可以同时提供配方和一个或多个先决条件(源文件)。如果您需要指定隐含规则不能提供的额外先决条件,比如头文件,那么您可能希望为 foo.o 编写没有配方的规则。
每个隐式规则都有一个目标模式和先决模式。可能有许多隐式规则具有相同的目标模式。例如,许多规则组成 ‘.o’ 文件:第一种,用 C 编译器从 ‘.c’ 文件生成;第二种,用Pascal编译器从 ‘.p’ 文件;等等。所以,如果你有一个文件 foo.c,make将运行C编译器;否则,如果你有一个文件 foo.p,make 将运行 Pascal 编译器;等等。
当然,在编写 makefile 时,您知道希望 make 使用哪个隐式规则,也知道它会选择那个,因为您知道应该存在哪些可能的先决条件文件。
在上面,我们说过,如果所需的先决条件"存在或可以制定",则适用隐含规则。如果在makefile中显式地提到文件作为目标或先决条件,或者可以递归地找到隐式规则来创建它,则可以创建该文件。当一个隐式先决条件是另一个隐式规则的结果时,我们就说发生了链接。
通常,为每个目标和每个没有配方的双冒号规则搜索隐式规则。只作为先决条件提及的文件被认为是一个目标,它的规则没有指定任何内容,因此会对它进行隐式规则搜索。
注意,显式先决条件不会影响隐式规则搜索。例如,请考虑以下显式规则:
foo.o: foo.p
foo.p 的先决条件并不一定意味着 make 将根据隐式规则重制 foo.o,从Pascal源文件到 .p 文件,生成一个对象文件,一个 .o 文件。
如果不希望将隐式规则用于没有配方的目标,则可以通过编写分号为该目标指定一个空配方。
二、内置规则目录
下面是预定义的隐式规则的目录,除非 makefile 显式覆盖或取消它们,否则这些规则始终可用。‘-r’ 或 ‘–no-builtin-rules’ 选项取消所有预定义规则。
本手册仅记录基于 posix 的操作系统上可用的默认规则。其他操作系统,如 VMS、Windows、OS/2 等。可能具有不同的默认规则集。要查看 GNU make 版本中可用的缺省规则和变量的完整列表,请在没有 makefile 的目录中运行 ‘make -p’。
并不是所有这些规则都会被定义,即使 ‘-r’ 选项没有被给出。许多预定义的隐式规则在 make 中作为后缀规则实现,因此将定义哪些规则取决于后缀列表(特殊目标 .SUFFIXES 的先决条件列表)。默认后缀列表为:
.out, .a, .ln, .o, .c, .cc, .C, .cpp, .p, .f, .F, .m, .r, .y, .l, .ym, .lm, .s, .S, .mod, .sym, .def, .h, .info, .dvi, .tex, .texinfo, .texi, .txinfo, .w, .ch .web, .sh, .elc, .el.
下面描述的所有隐式规则(其先决条件具有这些后缀之一)实际上都是后缀规则。如果修改后缀列表,则唯一有效的预定义后缀规则将是由您指定的列表中的一个或两个后缀命名的规则;后缀未在列表中的规则将被禁用。
1、编译 C 程序
n.o 是用 ‘$(CC) $(CPPFLAGS) $(CFLAGS) -c’ 形式的配方自动从 n.c 生成的。
2、编译 C++ 程序
n.o 是用 ‘$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c’ 形式的配方自动从 n.cc、n.cpp 或 n.C 生成的。我们鼓励您使用后缀 ‘.cc’ 来表示c++源文件,而不是后缀 ‘.C’。
3、编译 Pascal 程序
n.o 是用 ‘$(PC) $(PFLAGS) -c’ 形式的配方自动从 n.p 生成的。
4、编译 Fortran 和 Ratfor 程序
n.o 是通过运行Fortran编译器自动从 n.r、n.F 或 n.f 生成的。使用的精确配方如下:
-
‘.f’:‘$(FC) $(FFLAGS) -c’
-
‘.F’:‘$(FC) $(FFLAGS) $(CPPFLAGS) -c’、
-
‘.r’:‘(FC) $(FFLAGS) $(RFLAGS) -c’
5、预处理Fortran和Ratfor程序
n.f 是由 n.r 或 n.F自动合成的。此规则仅运行预处理器,以将 Ratfor 或预处理的 Fortran 程序转换为严格的 Fortran 程序。使用的精确配方如下:
- ‘.F’:‘$(FC) $(CPPFLAGS) $(FFLAGS) -F’
- ‘.r’:‘$(FC) $(FFLAGS) $(RFLAGS) -F’
6、编译 Modula-2 程

GNU make使用隐式规则和模式规则简化构建过程,自动处理常见的构建任务,如编译C/C++代码、预处理Fortran/Ratfor程序等。隐式规则基于文件扩展名,如‘%.o:%.c’表示从C源文件创建对象文件。模式规则允许更灵活的匹配,如‘%.o:%.cc’。中间文件是通过链式规则创建的,如Yacc和cc结合从.y文件生成.o文件。通过定义或覆盖变量,可以定制隐式规则的行为。最后,可以定义默认规则以处理没有明确规则的目标。

1552

被折叠的 条评论
为什么被折叠?



