这里总结 GNU make 所具备的特性,并借此与其他版本的 make 作比较、向它们致意。作为比较的基准,我们以 4.2 BSD 系统中 make 的特性为起点。如果你想编写可移植性高的 makefile,最好不要使用这里列出的特性,不兼容之处与未实现的功能章中列出的功能也是如此。
许多特性源自 System V 版本的 make。
VPATH 变量及其特殊含义。请参见为前置条件 (prerequisite) 搜索目录一节。该特性在 System V make 中也存在,但没有文档记载。4.3 BSD make 对其作了文档化(其中说明它模仿了 System V 的 VPATH 特性)。
MAKEFLAGS 变量,把选项传递给递归调用的 make。请参见向子 make 传达选项一节。
$% 被设置为归档引用中的成员名。请参见自动变量一节。
$@、$*、$<、$%、$? 都有对应的形式,如 $(@F) 和 $(@D)。GNU make 把这一点自然地推广到了 $^。请参见自动变量一节。
make 中,这些选项实际上会做某些事情。
MAKE 调用 make 的递归命令仍会执行。请参见make 的递归使用一节。
make 中已经过时,因为有了规则链这一通用机制(参见隐含规则链),只需一条用于把成员安装到归档中的模式规则(参见以归档成员为目标的隐含规则)就足够了。
接下来列出的特性,是从各种其他版本的 make 获得灵感的。其中有些情况,并不清楚究竟是哪个版本影响了哪个版本。
make 中实现。我们不确定最早是谁发明的,但它已经传播得相当广。请参见模式规则的定义与重定义一节。
make 中实现,后来 AT&T 贝尔实验室的 Andrew Hume 在他的 mk 程序中也实现了(他称之为「传递闭包(transitive closure)」)。我们其实并不知道这个想法是从他们某人那里得来的,还是在同一时期独立想到的。请参见隐含规则链一节。
$^。这并非我们发明,但我们也不知道是谁发明的。请参见自动变量一节。自动变量 $+ 是对 $^ 的一点扩展。
make 中为「-W」),据我们所知,是 Andrew Hume 在 mk 中发明的。请参见代替执行命令一节。
make 及类似程序中,只是 System V 和 BSD 的实现里没有。请参见命令的执行一节。
make 就已通过 patsubst 函数提供了这一功能。究竟是谁影响了谁,完全不清楚,因为在 SunOS 4 发布之前 GNU make 就已有 patsubst。
make。请参见向变量追加更多文本一节。
make。请参见以归档成员为目标一节。
-include 指令源自 SunOS 4 make。(但请注意,SunOS 4 make 不允许在一条 -include 指令里指定多个 makefile。)同样的功能在 SGI make 以及可能的其他实现中以 sinclude 的名字出现。
!= 这个 shell 赋值运算符存在于许多 BSD 版的 make 中,GNU make 在此特意实现为与那些实现的行为完全相同。
make 集成 GNU Guile 的做法类似。
其余特性是 GNU make 新创的发明:
make 的选项概要。
MAKE,把命令行上的变量赋值自动传递给递归的 make 调用。请参见make 的递归使用一节。
define 进行逐字原样的变量定义。请参见定义多行变量一节。
.PHONY 声明伪目标 (phony)。
AT&T 贝尔实验室的 Andrew Hume 也在他的 mk 程序中用不同的语法实现了类似的功能。这似乎是一个平行发现的例子。请参见伪目标 (phony)一节。
这一功能在各种版本的 make 中已被多次实现;它似乎是从 C 预处理器及类似宏语言的功能派生出来的自然扩展,并非革命性的概念。请参见Makefile 的条件分支一节。
MAKEFILES一节。
make 中,后缀必须以「.」开头,且不能包含「/」字符。
MAKELEVEL 记录当前 make 的递归深度。请参见make 的递归使用一节。
MAKECMDGOALS 提供命令行上给出的目标 (goal)。请参见指定目标的参数一节。
vpath 搜索。请参见为前置条件搜索目录一节。
make 也有这一功能极其有限的一种形式,即它会为 makefile 检出 SCCS 文件。
make 行为的动态对象。请参见加载动态对象一节。