MAKEFILE详解 书写规则 十

转自 http://www.cppblog.com/ivenher/articles/22094.html

MAKEFILE详解 书写规则 十

书写规则 
———— 

规则包含两个部分,一个是依赖关系,一个是生成目标的方法。 

在Makefile中,规则的顺序是很重要的,因为,Makefile中只应该有一个最终目标,其它的目标都是被这个目标所连带出来的,所以一定要让make知道你的最终目标是什么。一般来说,定义在Makefile中的目标可能会有很多,但是第一条规则中的目标将被确立为最终的目标。如果第一条规则中的目标有很多个,那么,第一个目标会成为最终的目标。make所完成的也就是这个目标。 

好了,还是让我们来看一看如何书写规则。 


一、规则举例 

    foo.o : foo.c defs.h       # foo模块 
            cc -c -g foo.c 

看到这个例子,各位应该不是很陌生了,前面也已说过,foo.o是我们的目标,foo.c和defs.h是目标所依赖的源文件,而只有一个命令“cc -c -g foo.c”(以Tab键开头)。这个规则告诉我们两件事: 

    1、 文件的依赖关系,foo.o依赖于foo.c和defs.h的文件,如果foo.c和defs.h的文件日期要比foo.o文件日期要新,或是foo.o不存在,那么依赖关系发生。 
    2、如果生成(或更新)foo.o文件。也就是那个cc命令,其说明了, 如何生成foo.o这个文件。(当然foo.c文件include了defs.h文件) 


二、规则的语法 

      targets : prerequisites 
        command 
        ... 

      或是这样:  

      targets : prerequisites ; command 
            command 
            ... 

targets是文件名,以空格分开,可以使用通配符。一般来说,我们的目标基本上是一个文件,但也有可能是多个文件。 

command是命令行,如果其不与“target:prerequisites”在一行,那么,必须以[Tab键]开头,如果和prerequisites在一行,那么可以用分号做为分隔。(见上) 

prerequisites也就是目标所依赖的文件(或依赖目标)。如果其中的某个文件要比目标文件要新,那么,目标就被认为是“过时的”,被认为是需要重生成的。这个在前面已经讲过了。 

如果命令太长,你可以使用反斜框(‘\’)作为换行符。make对一行上有多少个字符没有限制。规则告诉make两件事,文件的依赖关系和如何成成目标文件。 

一般来说,make会以UNIX的标准Shell,也就是/bin/sh来执行命令。 


三、在规则中使用 通配符 

如果我们想定义一系列比较类似的文件,我们很自然地就想起使用通配符。make支持三个通配符: “*”,“?”和“[...]”。这是和Unix的B-Shell是相同的。 

波浪号(“~”)字符在文件名中也有比较特殊的用途。如果是“~/test”,这就表示当前用户的$HOME目录下的test目录。而“~hchen/test”则表示用户hchen的宿主目录下的test目录。(这些都是Unix下的小知识了,make也支持)而在Windows或是MS-DOS下,用户没有宿主目录,那么波浪号所指的目录则根据环境变量“HOME”而定。 

通配符代替了你一系列的文件,如“*.c”表示所以后缀为c的文件。一个需要我们注意的是,如果我们的文件名中有通配符,如:“*”,那么可以用转义字符“\”,如“\*”来表示真实的“*”字符,而不是任意长度的字符串。 

好吧,还是先来看几个例子吧: 

    clean: 
         rm -f *.o 

    上面这个例子我不不多说了,这是操作系统Shell所支持的通配符。这是在命令中的通配符。 

    print: *.c 
         lpr -p $? 
         touch print 

    上面这个例子说明了通配符也可以在我们的规则中,目标print依赖于所有的[.c]文件。其中的“$?”是一个自动化变量,我会在后面给你讲述。 

    objects = *.o      (注: " =" 在使用的时候展开,如果赋值和使用之间右部变量发生改变,则取值发生变化


    上面这个例子,表示了,通符同样可以用在变量中。并不是说[*.o]会展开,不!objects的值就是“*.o”。Makefile中的变量其实就是C/C++中的宏。如果你要让通配符在变量中展开,也就是让objects的值是所有[.o]的文件名的集合,那么,你可以这样: 

    objects := $(wildcard *.o)     (注: " :=" 在赋值的时候就展开,以后不再变化) 这种用法由关键字“wildcard”指出,关于Makefile的关键字,我们将在后面讨论。 
相关文章
相关标签/搜索