GNU make特点的一些总结。主要是和其它版本make得比较。这些特征都是以4.2 BSD 中的make的为基准。当需要书写可移植到不同的类UNIX系统上的Makefile时,应避免使用GNU 版本make自身的一些特征。

一、      源自System v的特点

下面所罗列的这些是来自System V版本make的一些特点:

1、 变量“VPATH”及它的含义System V版本的make支持,但没有得到验证。4.3 BSD make支持(据说是对System Vmake这一功能的仿照)。

2、 可包含其它makefile文件。使用指示符“include”可同时包含多个文件是GNU的扩展。

3、  可使用系统环境变量。

4、 变量“MAKEFLAGS”。用于make递归调用时传递命令行选项。

5、 make静态库(文档文件)是“$%”可代表静态库成员名。

6、对自动变量“$@”、“$*”、“$<”、“$%”和“$?”进行了扩展,支持“$(@F)”和“$(@D)”等形式的自动环变量。并以此对自动变量“$^”进行了扩展。

7、变量引用。

8、支持使用命令行选项“-b”和“-m”来兼容其它版本的makeSystem V make中,这些选项有实际含义。

9、使用变量“MAKE”执行的递归调用。可支持“-n”、“-q”和“-t”向子make进程的传递。

10、支持后缀“.a”(静态库的后缀规则 )。不过这个特点在GNU make的新版本中已经被模式规则所取代。

11、保持Makefile规则命令行的书写格式,只是去掉了初始空字符。执行命令的回显保持Makefile中的书写格式不变。

二、  源自其他版本的特点

下面的特点来自于其它版本的make,但每一个特征来自由哪个版本的make不太清楚:

1、模式规则使用模式字符“%”。目前在多个不同版本的make中都有使用“%”。但具体是那个版本的make提出它不甚清楚。

2、规则链以及隐含的中间过程文件。这个特点首次是在Stu Feldman make版本中实现,并用于AT&T第八版的Unix研究中。后来AT&T贝尔实验室的Andrew Hume 在它的mk程序中应用(这里称为“传递闭合”)。但不清楚这个特征是对它们的继承还是GNU自己的重新实现。

3、包含规则所有依赖文件列表的自动化变量“$^”。可以确定这不是GNU创造的,但具体是哪个版本的make创造也不清楚。

4、命令行的“what if”选项(GNU make的“-W”选项)据说是Andrew Hume mk中首次提出的的。

5、并发执行的观点,在其它多种版本的make中都有支持。但System V BSD 没有实现此功能。

6、变量的模式替换引用来自SunOS 4GNU make中,这个功能是在SunOS 4实现之前由函数“patsubst”提供。同一功能的两种实现,在两个版本的make中,难以确定是哪一个最早提出这个概念。

7、命令行之前使用“+”字符,它有特殊的含义。这种做法是由IEEE Standard 1003.2-1992 (POSIX.2)定义的。

8、变量值追加“+=”的语法来自于SunOS 4 版本的make

9、静态库成员列表作为目标的语法“ARCHIVE(MEM1 MEM2...)”源自SunOS 4 make

10、使用“-include”包括多个其它的makefile文件,当所包含的文件不存在时不出错。这个特征源自SunOS 4 版本的make。(但SunOS 4版本的make不能使用单指示符同时包含多个文件) GNU make的这个特征和SGI make 的指示符“sinclude”相同。GNU make也支持“sinclude”。

三、GNU make自身的特点

以下特点是由GNU make本身的:

1、命令行选项“-v”或“--version”打印make的版本和版权信息。

2、  使用“-h”或“--help”列出make支持的所有命令行选项。

3、直接展开式变量。

4、变量“MAKE”支持make递归调用时命令行选项的传递。

5、命令选项“-C”或“--directory”改变make执行的工作目录。

6、支持多行变量的定义。

7、使用特殊目标“.PHONY”声明伪目标。AT&T 贝尔实验室Andrew Hume 使用不同的语法在它的mk程序中也实现了该功能。两者几乎在同时支持。

8、支持过程文本处理函数。

9、支持使用“-o”或者“--old-file”选项指定一个文件是未修改文件(告诉make不需要考虑这个文件的时间戳)。

10、条件执行。众多其它版本的make也支持;它似乎是对c语言预处理程序和宏语言的自然扩展,不能算是一个全新的概念。

11、指定包含makefile文件的搜寻路径VPATH。

12、环境变量“MAKEFILES”指定需要默认读取的makefile文件。

13、去除文件名中的“./”,因此“./file”和“file”等价。

14、支持在规则依赖中使用“-lNAME”来指定连接库。

15、允许后缀规则中后缀名可以是任何字符串。其它版本make中后缀必须以“.”开始,并且后缀中不能包含斜杠“/”。

16、内嵌变量“MAKELEVEL”,这个变量被用来跟踪make递归调用过程调用深度。

17、内嵌变量“MAKECMDGOALS”,这个变量代表了make执行的终极目标。

18、指定静态模式规则。

19、支持选择性搜索关键字“vpath”。

20、支持计算的变量引用。

21、支持自动重建makefile文件

22、多个新的内嵌隐含规则。

23、内嵌变量“MAKE_VERSION”代表当前的make版本。

四、和其他版本的兼容问题

GNU make存在一些和其它版本make不兼容的功能,其它版本make具有的部分功能,在GNU make中也没有实现。POSIX.2 标准 IEEE Standard 1003.2-1992)没有规定以下的这些特点需要在make中实现。

1、形如“FILE((ENTRY))”的目标代表静态库文件“FILE”的一个成员。它的成员不是用文件名,而是一个定义了连接符号“ENTRY”的.o文件。GNU make没有支持它的原因是:书写这样的规则要求书写者对静态库内部符号索引表熟悉。

2、以字符“~ 结尾的后缀在System V make的后缀规则中有特别的含义;它指的是对应目标文件的依赖文件是没有“~”的SCCS 文件。例如,System V的后缀规则“.c~.o”含义是:“N.o”是从SCCS文件“s.N.c”中提取的。为了完全覆盖,可能需要一系列的这样的规则。GNU make对它的处理是:使用两个模式规则从SCCS文件抽取一个文件,这两个模式规则形成一个隐含规则链。

3、System V 4.3 BSD make中,通过“VPATH”指定的目录搜寻的文件,对应的文件名需要经过make改变后才加入对应规则到命令行中。GNU make使用自动环变量来实现这一功能。

4、在一些Unixmake中,自动化变量“$*作为规则的依赖时,具有奇怪的特征:它会被扩展为该规则的目标全名。它和GNU make中“$*”的含义完全不同。

5、  在一些Unixmake中。会为所有目标搜索隐含规则,不仅仅对那些没有命令的目标。就是说如果我们的规则时这样的话:

foo.o:

       cc -c foo.c

这种版本的make就会认为目标“foo.o”的依赖文件是“foo.c”。

我们认为make的这种处理方法容易导致混乱。因为Makefile已经对目标有明确的定义,而在为目标搜索隐含规则是不合逻辑的。因此GNU make没有支持这种方式的规则处理。

6、GNU make不包含任何编译以及预处理EFL程序的内嵌隐含规则。如果其它那种版本的make已经实现了这个特性,我们会很乐意地把它加入到GNU make支持的特性中。

7、 SVR4版本的make中,一个没有命令的后缀规则被作为一个空命令规则来处理。例如:

.c.a:

这个规则将覆盖内嵌的目标为“.c.a”的规则。

GNU make对这个规则的行为是为目标.a添加一个依赖类型.c。上述的行为在GNU make中的实现是:

.c.a: ;

8、一些版本的make 在调用shell时使用“-e”参数告诉shell,在除执行“make -k”时,一旦命令行执行失败(返回状态非0)就立即退出。我们认为对于不同的命令的执行结果要视情况来处理。因此GNU make的没有支持这种方式。

 


posted on 2011-12-06 23:08  风行雪舞  阅读(735)  评论(0编辑  收藏  举报
无觅相关文章插件,快速提升流量