makefile笔记(2)

来源:互联网 发布:外包软件开发公司 编辑:程序博客网 时间:2024/06/10 21:28

书写规则


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

     makefile中规则的顺序很重要,因为makefile中只有一个最终目标,这个目标一定要卸载第一个。
     基本规则就是 :

  目标 :对应的依赖      命令
  • makefile中的通配符

makefile支持三个通配符:“*”,“?”,“[ … ]”。波浪号(“~”)在文件命中有比较特殊的用途。eg:“~/test”,表示当前用户的$HOME目录下的text目录。“~isstack/test”表示在用户isstack的宿主目录下的test目录。windows下用户没有宿主目录,则都指环境变量“HOME”。
 * 指匹配所有字符,如 *.c 匹配所有c文件。* 可以用在命令中和shell一样,也可以用在规则中,同样可以用在变量中,eg:
 

objects = *.o  

 但是并不是说定义的时候就会直接展开获得所有.o 文件,objects的值就是“*.o” ,相当于C中的宏,若想要通配符在变量中就展开,可以:
 

 objects := $(wildcard *.o)   

   wildcard是makefile的关键字。
 


  • 文件搜索

在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存
放在不同的目录中。所以,当 make 需要去找寻文件的依赖关系时,你可以在文件前加上路
径,但最好的方法是把一个路径告诉 make,让make 在自动去找。

Makefile 文件中的特殊变量“VPATH”就是完成这个功能的,如果没有指明这个变量,
make 只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,那么,make
就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。

VPATH = src:../headers   

上面的的定义指定两个目录,“src”和“../headers”,make 会按照这个顺序进行搜 索。目录由“冒号”分隔。(当然,当前目录永远是最高优先搜索的地方)

 另一个设置文件搜索路径的方法是使用 make 的“vpath”关键字(注意,它是全小写 的),这不是变量,这是一个 make 的关键字,这和上面提到的那个 VPATH 变量很类似,但是 它更为灵活。它可以指定不同的文件在不同的搜索目录中。这是一个很灵活的功能。它的使
用方法有三种:

1、vpath
 为符合模式的文件指定搜索目录。

2、vpath
 清除符合模式的文件的搜索目录。

3、vpath
 清除所有已被设置好了的文件搜索目录。

 vapth 使用方法中的需要包含“%”字符。“%”的意思是匹配零或若干字符,
例如,“%.h”表示所有以“.h”结尾的文件。指定了要搜索的文件集,而
则指定了的文件集的搜索的目录。例如:

vpath %.h ../headers   

 该语句表示,要求 make 在“../headers”目录下搜索所有以“.h”结尾的文件。(如果 某文件在当前目录没有找到的话)可以继续使用vpath语句,以指定不同搜索策略。
 

vpath %.c foo:barvpath % blish

上面的语句表示 .c 文件先是在 foo目录,然后是bar目录,最后是blish目录。


  • 伪目标

接触过的clean便是一个伪目标,make时并不生成clean 这个文件,它只是一个标签,伪目标的名字不能和文件名重名,不然便失去了伪目标的意义。
 为了避免和文件重名的情况,引入了一个特殊的标记 “.PHONY”来明确表示这是一个伪目标。
 .PHONY : clean
 只要有这个声明,不管是否有clean,只要make clean 才能运行clean 。
 
 伪目标一般没有依赖的文件。但是,我们也可以为伪目标指定所依赖的文件。伪目标同 样可以作为“默认目标”,只要将其放在第一个。一个示例就是,如果你的 Makefile 需要 一口气生成若干个可执行文件,但你只想简单地敲一个 make 完事,并且,所有的目标文件
都写在一个 Makefile 中,那么你可以使用“伪目标”这个特性:

all : prog1 prog2 prog3   .PHONY : all   prog1 : prog1.o utils.o   cc -o prog1 prog1.o utils.o   prog2 : prog2.o   cc -o prog2 prog2.o   prog3 : prog3.o sort.o utils.o   cc -o prog3 prog3.o sort.o utils.o   

 我们知道,Makefile 中的第一个目标会被作为其默认目标。我们声明了一个“all”的 伪目标,其依赖于其它三个目标。由于伪目标的特性是,总是被执行的,所以其依赖的那三 个目标就总是不如“all”这个目标新。所以,其它三个目标的规则总是会被决议。也就达 到了我们一口气生成多个目标的目的。“.PHONY : all”声明了“all”这个目标为“伪目 标”。

 随便提一句,从上面的例子我们可以看出,目标也可以成为依赖。所以,伪目标同样也 可成为依赖。看下面的例子:

.PHONY: cleanall cleanobj cleandiff   cleanall : cleanobj cleandiff   rm program   cleanobj :   rm *.o   cleandiff :   rm *.diff   

“make clean”将清除所有要被清除的文件。“cleanobj”和“cleandiff”这两个伪 目标有点像“子程序”的意思。我们可以输入“make cleanall”和“make cleanobj”和“make cleandiff”命令来达到清除不同种类文件的目的。

原创粉丝点击