Makefile(1)

Makefile的约定

1.基本的约定

本节讨论的是书写Makefile中需要的一些基本约定,由于不同版本make之间的一些差异。可能在GNU make环境中正常工作的Makefile,换成其它版本的make执行时会发生错误。为了最大可能的兼容不同版本的make,这里给出了一些基本的约定。

1.        所有的Makefile中应该包含这样一行:

SHELL = /bin/sh

这样做的目的是为了避免变量“SHELL”在有些系统上可能继承同名的系统环境变量而导致错误。虽然在GNU版本的make中不会出现这种问题(GNU make中变量“SHELL”的默认值是“/bin/sh”,它不同于系统环境变量“SHELL”)。

2.        小心处理后缀和隐含规则。不同make的可识别后缀和隐含规则存在不兼容,它可能会导致混乱或者错误。因此在特定Makefile中明确限定可识别的后缀是一个不错的注意。Makefile中应该这样做:

.SUFFIXES:

.SUFFIXES: .c .o

第一行首先取消掉make默认的可识别后缀列表,第二行通过特殊目标“.SUFFIXES”重新指定可识别的

后缀规则。

3.        小心处理规则中的路径。当需要处理指定目录的的文件时,需要明确指定路径。如“./”代表当前目录,“$(srcdir)”代表源代码目录。当没有指定明确路径时,意味着是当前目录。

目录“./”(当前目录,GNU的发布软件包中的“build”目录)和“$(srcdir)”的区别和重要,我们可以通过“configure”脚本的选项“--srcdir”指定源代码所在的目录(可参考GNU发布的软件包中的configure脚本)。当源代码目录和build目录不同时,规则:

foo.1 : foo.man sedscript

        sed –e sedscript foo.man > $@

将执行失败,是因为“foo.man”和“sedscript”并不在当前目录(当然,处理这种错误的手段可能有很多,诸如使用变量“VPATH”等)。当前目录只是build目录,并不是软件包目录。

4.        使用GNU make的变量“VPATH”指定搜索目录。当规则只有一个依赖文件时。我们应该使用自动化变量“$<”和“$@”代替出现在命令的依赖文件和目标文件(其它版本的make,只在隐含规则中设置自动化变量“$<”)。对于一个这样的目标:

foo.o : bar.c

       $(CC) – I. –I$(srcdir) $(CFLAGS) –c bar.o –o foo.o

我们在Makefile中应该是用这种方式来书写:

foo.o : bar.c

       $(CC) – I. –I$(srcdir) $(CFLAGS) –c $< –o $@

另外,对于有多个依赖的规则,为了规则能被正确执行。应该在规则的命令行中明确的指定文件的完整路径名。例如第一个例子就可以这样写(需要在规则之前使用“VPATH”指定搜索目录):

foo.1 : foo.man sedscript

       sed –e $(srcdir)/sedscript $(srcdir)/foo.man > $@

GNU的发布软件包中,包括了很多非源代码的文件。诸如:“info”文件、“Autoconf”的输出文件、“Automake”、“Bison”或者“Flex”等文件。这些文件在发布时就在源代码的目录中。因此Makefile中对它们的重建也应该是在源代码目录,而不应该在build目录。

相反的,对于那些本来就不存在于源代码目录下的文件,也不应该将它们创建在源代码的目录下。要记住,make的过程不应该以任何方式修改源代码,或者改变源代码目录的结构。

2.规则命令行的约定

本节将讨论书写规则命令的一些约定,在书写多系统兼容的Makefile时,特别需要注意不同系统之间的命令的不兼容。这里对规则命令行做出了一些基本约定:

1.        书写Makefile时,规则的命令(包括其他的脚本文件,如:configure)应该是“sh”而不因该是“csh”所支持的。

2.        用于创建和安装的“configure”脚本和Makefile中的命令除下面所列出的意外,避免使用其它命令:

cat cmp cp diff echo egrep expr false grep install-info

ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true

3.        在目标“dist”的命令行中可以使用压缩工具“gzip”。

4.        对于可使用的这些工具命令,尽量使用它的通用选项。不要使用那些只在特定系统上有效的选项。如:“mkdir -p”这个命令在Linux系统上能够很好的工作,但是其它很多系统却并不支持“mkdir”的“-p”选项。

5.        尽量不要在规则的命令行重创建符号连接文件(使用“ln”命令)。因为有些系统不支持(对于类Unix的系统我们基本上没有问题,可能这里所说的是MS-DOS系统的系统。我想大家也没有兴趣或者说没有必要在MS-DOS下写Makefile,所以这个限制基本可以不考虑)。

6.        重建或者安装目标(一般是伪目标)的命令行可使用编译器或者相关工具程序,应该使用一个变量来表示所要执行的命令。这样会比较方便,需要修改一个命令时,只需要更改变量的值就可以了。对于以下的这些命令程序:

ar  bison  cc  flex  install  ld  ldconfig  lex

make  makeinfo  ranlib  texi2dvi  yacc

Makefile规则中的命令行中,使用以下这些变量来代替它们:

$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG) $(LEX)

$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)

如果在规则的命令行需要使用“ranlib”或者“ldconfig

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值