Makefile简介1

来源:互联网 发布:东莞好玩的地方知乎 编辑:程序博客网 时间:2024/06/07 06:22

1、Makefile的规则

目标文件:依赖文件
[tab键] 执行的命令(任意的Shell命令)
每个命令行前都必须有tab符号。
举例:
foo.o: foo.c defs.h # foo模块
gcc -c -g foo.c

2、在规则中使用通配符

make支持三各通配符:“*”,“?”和“[…]”。这是和Unix的B-Shell是相同的。

3、文件搜寻

3.1 VPATH 方式

VPATH = src:../headers
make就会在当当前目录找不到的情况下,到上面的的定义指定两个目录,“src”和“../headers”,并按顺序进行搜索。目录由“冒号”分隔。(当然,当前目录永远是最高优先搜索的地方)

3.2 vpath方式

这是一个很灵活的功能。它的使用方法有三种:

  1. vpath < pattern> < directories> 为符合模式< pattern>的文件指定搜索目录。
  2. vpath < pattern> 清除符合模式< pattern>的文件的搜索目录。
  3. vpath 清除所有已被设置好了的文件搜索目录。

  vapth使用方法中的< pattern>需要包含“%”字符。“%”的意思是匹配零或若干字符,例如,“%.h”表示所有以“.h”结尾的文件。< pattern>指定了要搜索的文件集,而< directories>则指定了的文件集的搜索的目录。例如:
vpath %.h ../headers
该语句表示,要求make在“../headers”目录下搜索所有以“.h”结尾的文件。(如果某文件在当前目录没有找到的话)
我们可以连续地使用vpath语句,以指定不同搜索策略。如果连续的vpath语句中出现了相同的< pattern>,或是被重复了的< pattern>,那么,make会按照vpath语句的先后顺序来执行搜索。如:
vpath %.c foo
vpath %.c blish
vpath %.c bar
其表示“.c”结尾的文件,先在“foo”目录,然后是“blish”,最后是“bar”目录。
vpath %.c foo:bar
vpath %.c blish
而上面的语句则表示“.c”结尾的文件,先在“foo”目录,然后是“bar”目录,最后才是“blish”目录。

4、伪目标

为了避免和文件重名的这种情况,我们可以使用一个特殊的标记“.PHONY”来显示地指明一个目标是“伪目标”,不管是否有“clean”文件,要运行“clean”这个目标,只有“make clean”这样。于是整个过程可以这样写:

    .PHONY: clean   clean:           rm *.o temp

伪目标同样也可成为依赖。看下面的例子:

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

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

5、多目标

bigoutput littleoutput : text.g           generate text.g -$(subst output,,$@) > $@

上述规则等价于:

   bigoutput : text.g           generate text.g -big > bigoutput   littleoutput : text.g           generate text.g -little > littleoutput

 其中,-$(subst output,,$@)中的“$”表示执行一个Makefile的函数,函数名为subst,后面的为参数。关于函数,将在后面讲述。这里的这个函数是截取字符串的意思,“$@”表示目标的集合,就像一个数组,“$@”依次取出目标,并执于命令。

6、静态模式

看一个例子:

   objects = foo.o bar.o   all: $(objects)   $(objects): %.o: %.c           $(CC) -c $(CFLAGS) $< -o $@

上面的例子中,指明了我们的目标从$object中获取,“%.o”表明要所有以“.o”结尾的目标,也就是“foo.o bar.o”,也就是变量$object集合的模式,而依赖模式“%.c”则取模式“%.o”的“%”,也就是“foobar”,并为其加下“.c”的后缀,于是,我们的依赖目标就是“foo.cbar.c”。而命令中的“$<”“$@”则是自动化变量,“$<”表示所有的依赖目标集(也就是“foo.c bar.c”),“$@”表示目标集。于是,上面的规则展开后等价于下面的规则:

   foo.o : foo.c           $(CC) -c $(CFLAGS) foo.c -o foo.o   bar.o : bar.c           $(CC) -c $(CFLAGS) bar.c -o bar.o

7、显示命令

@echo 正在编译XXX模块……
  当make执行时,会输出“正在编译XXX模块……”字串,但不会输出命令,如果没有“@”,那么,make将输出:
echo 正在编译XXX模块……
正在编译XXX模块……
  如果make执行时,带入make参数“-n”或“–just-print”,那么其只是显示命令,但不会执行命令,这个功能很有利于我们调试我们的Makefile,看看我们书写的命令是执行起来是什么样子的或是什么顺序的。
而make参数“-s”或“–slient”则是全面禁止命令的显示。

0 0
原创粉丝点击