bug fixed

This commit is contained in:
Dongdong Tian
2014-03-07 14:00:09 +08:00
parent 13b125042e
commit aadc6931a3
9 changed files with 195 additions and 153 deletions

View File

@@ -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))
#. 由12两步,可写出编译并链接所有“.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]文件: