您的位置:首页 > 其它

makefile笔记(2)

2017-09-01 20:06 92 查看

书写规则

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

 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:bar
vpath % 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”命令来达到清除不同种类文件的目的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  makefile