bug fixed
This commit is contained in:
@@ -55,7 +55,7 @@ prerequisites也就是目标所依赖的文件(或依赖目标)。如果其
|
||||
|
||||
波浪号(“~”)字符在文件名中也有比较特殊的用途。如果是“~/test”,这就表示当前用户的$HOME目录下的test目录。而 “~hchen/test”则表示用户hchen的宿主目录下的test目录。(这些都是Unix下的小知识了,make也支持)而在Windows或是 MS-DOS下,用户没有宿主目录,那么波浪号所指的目录则根据环境变量“HOME”而定。
|
||||
|
||||
通配符代替了你一系列的文件,如“*.c”表示所以后缀为c的文件。一个需要我们注意的是,如果我们的文件名中有通配符,如:“*”,那么可以用转义字符“\”,如“\*”来表示真实的“*”字符,而不是任意长度的字符串。
|
||||
通配符代替了你一系列的文件,如“*.c”表示所以后缀为c的文件。一个需要我们注意的是,如果我们的文件名中有通配符,如:“\*”,那么可以用转义字符“\\”,如“\\\*”来表示真实的“\*”字符,而不是任意长度的字符串。
|
||||
|
||||
好吧,还是先来看几个例子吧:
|
||||
|
||||
@@ -96,25 +96,25 @@ prerequisites也就是目标所依赖的文件(或依赖目标)。如果其
|
||||
|
||||
#. 列出一确定文件夹中的所有“.c”文件。
|
||||
|
||||
.. code-block:: makefile
|
||||
.. code-block:: makefile
|
||||
|
||||
objects := $(wildcard *.c)
|
||||
objects := $(wildcard *.c)
|
||||
|
||||
#. 列出(1)中所有文件对应的".o"文件,在(3)中我们可以看到它是由make自动编译出的。
|
||||
#. 列出(1)中所有文件对应的“.o”文件,在(3)中我们可以看到它是由make自动编译出的。
|
||||
|
||||
.. code-block:: makefile
|
||||
.. code-block:: makefile
|
||||
|
||||
$(patsubst %.c,%.o,$(wildcard *.c))
|
||||
$(patsubst %.c,%.o,$(wildcard *.c))
|
||||
|
||||
#. 由(1)(2)两步,可写出编译并链接所有“.c"和”.o"文件
|
||||
#. 由(1)(2)两步,可写出编译并链接所有“.c”和”.o“文件
|
||||
|
||||
.. code-block:: makefile
|
||||
.. code-block:: makefile
|
||||
|
||||
objects := $(patsubst %.c,%.o,$(wildcard *.c))
|
||||
foo : $(objects)
|
||||
cc -o foo $(objects)
|
||||
objects := $(patsubst %.c,%.o,$(wildcard *.c))
|
||||
foo : $(objects)
|
||||
cc -o foo $(objects)
|
||||
|
||||
这种用法由关键字“wildcard”,“patsubst"指出,关于Makefile的关键字,我们将在后面讨论。
|
||||
这种用法由关键字“wildcard”,“patsubst”指出,关于Makefile的关键字,我们将在后面讨论。
|
||||
|
||||
文件搜寻
|
||||
--------
|
||||
@@ -140,7 +140,7 @@ Makefile文件中的特殊变量“VPATH”就是完成这个功能的,如果
|
||||
\ ``vpath``\
|
||||
清除所有已被设置好了的文件搜索目录。
|
||||
|
||||
vapth使用方法中的<pattern>需要包含“%”字符。“%”的意思是匹配零或若干字符,(需引用“%”,使用“\%")例如,“%.h”表示所有以 “.h”结尾的文件。<pattern>指定了要搜索的文件集,而<directories>则指定了< pattern>的文件集的搜索的目录。例如:
|
||||
vapth使用方法中的<pattern>需要包含“%”字符。“%”的意思是匹配零或若干字符,(需引用“%”,使用“\\%”)例如,“%.h”表示所有以 “.h”结尾的文件。<pattern>指定了要搜索的文件集,而<directories>则指定了< pattern>的文件集的搜索的目录。例如:
|
||||
|
||||
.. code-block:: makefile
|
||||
|
||||
@@ -209,7 +209,7 @@ vapth使用方法中的<pattern>需要包含“%”字符。“%”的意思是
|
||||
prog3 : prog3.o sort.o utils.o
|
||||
cc -o prog3 prog3.o sort.o utils.o
|
||||
|
||||
我们知道,Makefile中的第一个目标会被作为其默认目标。我们声明了一个“all”的伪目标,其依赖于其它三个目标。由于默认目标的特性是,总是被执行的,但由于“all”又是一个伪目标,伪目标只是一个标签不会生成文件,所以不会有“all”文件产生。于是,其它三个目标的规则总是会被决议。也就达到了我们一口气生成多个目标的目的。“.PHONY : all”声明了“all”这个目标为“伪目标”。(注:这里的显式 “.PHONY : all" 不写的话一般情况也可以正确的执行,这样 make 可通过隐式规则推导出, “all" 是一个伪目标,执行 make 不会生成 ”all" 文件,而执行后面的多个目标。建议:显式写出是一个好习惯。)
|
||||
我们知道,Makefile中的第一个目标会被作为其默认目标。我们声明了一个“all”的伪目标,其依赖于其它三个目标。由于默认目标的特性是,总是被执行的,但由于“all”又是一个伪目标,伪目标只是一个标签不会生成文件,所以不会有“all”文件产生。于是,其它三个目标的规则总是会被决议。也就达到了我们一口气生成多个目标的目的。“.PHONY : all”声明了“all”这个目标为“伪目标”。(注:这里的显式 “.PHONY : all” 不写的话一般情况也可以正确的执行,这样make可通过隐式规则推导出, “all” 是一个伪目标,执行make不会生成“all”文件,而执行后面的多个目标。建议:显式写出是一个好习惯。)
|
||||
|
||||
随便提一句,从上面的例子我们可以看出,目标也可以成为依赖。所以,伪目标同样也可成为依赖。看下面的例子:
|
||||
|
||||
@@ -266,9 +266,9 @@ target-parrtern是指明了targets的模式,也就是的目标集模式。
|
||||
|
||||
prereq-parrterns是目标的依赖模式,它对target-parrtern形成的模式再进行一次依赖目标的定义。
|
||||
|
||||
这样描述这三个东西,可能还是没有说清楚,还是举个例子来说明一下吧。如果我们的<target-parrtern>定义成“%. o”,意思是我们的<target>;集合中都是以“.o”结尾的,而如果我们的<prereq-parrterns>定义成 “%.c”,意思是对<target-parrtern>所形成的目标集进行二次定义,其计算方法是,取<target-parrtern>模式中的“%”(也就是去掉了[.o]这个结尾),并为其加上[.c]这个结尾,形成的新集合。
|
||||
这样描述这三个东西,可能还是没有说清楚,还是举个例子来说明一下吧。如果我们的<target-parrtern>定义成“%.o”,意思是我们的<target>;集合中都是以“.o”结尾的,而如果我们的<prereq-parrterns>定义成 “%.c”,意思是对<target-parrtern>所形成的目标集进行二次定义,其计算方法是,取<target-parrtern>模式中的“%”(也就是去掉了[.o]这个结尾),并为其加上[.c]这个结尾,形成的新集合。
|
||||
|
||||
所以,我们的“目标模式”或是“依赖模式”中都应该有“%”这个字符,如果你的文件名中有“%”那么你可以使用反斜杠“\”进行转义,来标明真实的“%”字符。
|
||||
所以,我们的“目标模式”或是“依赖模式”中都应该有“%”这个字符,如果你的文件名中有“%”那么你可以使用反斜杠“\\”进行转义,来标明真实的“%”字符。
|
||||
|
||||
看一个例子:
|
||||
|
||||
@@ -290,7 +290,7 @@ prereq-parrterns是目标的依赖模式,它对target-parrtern形成的模式
|
||||
bar.o : bar.c
|
||||
$(CC) -c $(CFLAGS) bar.c -o bar.o
|
||||
|
||||
试想,如果我们的“%.o”有几百个,那种我们只要用这种很简单的“静态模式规则”就可以写完一堆规则,实在是太有效率了。“静态模式规则”的用法很灵活,如果用得好,那会一个很强大的功能。再看一个例子:
|
||||
试想,如果我们的“%.o”有几百个,那么我们只要用这种很简单的“静态模式规则”就可以写完一堆规则,实在是太有效率了。“静态模式规则”的用法很灵活,如果用得好,那会一个很强大的功能。再看一个例子:
|
||||
|
||||
.. code-block:: makefile
|
||||
|
||||
@@ -301,7 +301,7 @@ prereq-parrterns是目标的依赖模式,它对target-parrtern形成的模式
|
||||
$(filter %.elc,$(files)): %.elc: %.el
|
||||
emacs -f batch-byte-compile $<
|
||||
|
||||
$(filter %.o,$(files))表示调用Makefile的filter函数,过滤“$files”集,只要其中模式为“%.o”的内容。其的它内容,我就不用多说了吧。这个例子展示了Makefile中更大的弹性。
|
||||
$(filter %.o,$(files))表示调用Makefile的filter函数,过滤“$files”集,只要其中模式为“%.o”的内容。其它的内容,我就不用多说了吧。这个例子展示了Makefile中更大的弹性。
|
||||
|
||||
自动生成依赖性
|
||||
--------------
|
||||
@@ -344,7 +344,7 @@ gcc -MM main.c的输出则是::
|
||||
|
||||
那么,编译器的这个功能如何与我们的Makefile联系在一起呢。因为这样一来,我们的Makefile也要根据这些源文件重新生成,让 Makefile自已依赖于源文件?这个功能并不现实,不过我们可以有其它手段来迂回地实现这一功能。GNU组织建议把编译器为每一个源文件的自动生成的依赖关系放到一个文件中,为每一个“name.c”的文件都生成一个“name.d”的Makefile文件,[.d]文件中就存放对应[.c]文件的依赖关系。
|
||||
|
||||
于是,我们可以写出[.c]文件和[.d]文件的依赖关系,并让make自动更新或自成[.d]文件,并把其包含在我们的主Makefile中,这样,我们就可以自动化地生成每个文件的依赖关系了。
|
||||
于是,我们可以写出[.c]文件和[.d]文件的依赖关系,并让make自动更新或生成[.d]文件,并把其包含在我们的主Makefile中,这样,我们就可以自动化地生成每个文件的依赖关系了。
|
||||
|
||||
这里,我们给出了一个模式规则来产生[.d]文件:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user