update introduction

This commit is contained in:
Dongdong Tian 2016-02-20 10:55:25 +08:00
parent 8fa0788da2
commit 9bb399d30d

View File

@ -24,11 +24,11 @@ makefile的规则
... ...
target target
可以是一个object file(目标文件)也可以是一个执行文件还可以是一个标签label。对于标签这种特性在后续的“伪目标”章节中会有叙述。 可以是一个object file(目标文件)也可以是一个执行文件还可以是一个标签label。对于标签这种特性在后续的“伪目标”章节中会有叙述。
prerequisites prerequisites
就是要生成那个target所需要的文件或是目标。 生成该target所依赖的文件和/或target
command command
也就是make需要执行的命令。任意的shell命令 该target要执行的命令任意的shell命令
这是一个文件的依赖关系也就是说target这一个或多个的目标文件依赖于prerequisites中的文件其生成规则定义在command中。说白一点就是说:: 这是一个文件的依赖关系也就是说target这一个或多个的目标文件依赖于prerequisites中的文件其生成规则定义在command中。说白一点就是说::
@ -41,7 +41,7 @@ command
一个示例 一个示例
-------- --------
正如前面所说如果一个工程有3个头文件和8个c文件我们为了完成前面所述的那三个规则我们的makefile应该是下面的这个样子的。 正如前面所说如果一个工程有3个头文件和8个c文件为了完成前面所述的那三个规则我们的makefile应该是下面的这个样子的。
.. code-block:: makefile .. code-block:: makefile
@ -70,7 +70,7 @@ command
rm edit main.o kbd.o command.o display.o \ rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o insert.o search.o files.o utils.o
反斜杠( ``\`` 是换行符的意思。这样比较便于makefile的读。我们可以把这个内容保存在名字为“makefile”或“Makefile”的文件中然后在该目录下直接输入命令 ``make`` 就可以生成执行文件edit。如果要删除执行文件和所有的中间目标文件那么只要简单地执行一下 ``make clean`` 就可以了。 反斜杠( ``\`` 是换行符的意思。这样比较便于makefile的读。我们可以把这个内容保存在名字为“makefile”或“Makefile”的文件中然后在该目录下直接输入命令 ``make`` 就可以生成执行文件edit。如果要删除执行文件和所有的中间目标文件那么只要简单地执行一下 ``make clean`` 就可以了。
在这个makefile中目标文件target包含执行文件edit和中间目标文件 ``*.o`` 依赖文件prerequisites就是冒号后面的那些 ``.c`` 文件和 ``.h`` 文件。每一个 ``.o`` 文件都有一组依赖文件,而这些 ``.o`` 文件又是执行文件 ``edit`` 的依赖文件。依赖关系的实质就是说明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。 在这个makefile中目标文件target包含执行文件edit和中间目标文件 ``*.o`` 依赖文件prerequisites就是冒号后面的那些 ``.c`` 文件和 ``.h`` 文件。每一个 ``.o`` 文件都有一组依赖文件,而这些 ``.o`` 文件又是执行文件 ``edit`` 的依赖文件。依赖关系的实质就是说明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。
@ -155,7 +155,7 @@ makefile中使用变量
GNU的make很强大它可以自动推导文件以及文件依赖关系后面的命令于是我们就没必要去在每一个 ``.o`` 文件后都写上类似的命令因为我们的make会自动识别并自己推导命令。 GNU的make很强大它可以自动推导文件以及文件依赖关系后面的命令于是我们就没必要去在每一个 ``.o`` 文件后都写上类似的命令因为我们的make会自动识别并自己推导命令。
只要make看到一个 ``.o`` 文件,它就会自动的把 ``.c`` 文件加在依赖关系中如果make找到一个 ``whatever.o`` ,那么 ``whatever.c`` 就会是 ``whatever.o`` 的依赖文件。并且 ``cc -c whatever.c`` 也会被推导出来于是我们的makefile再也不用写得这么复杂。我们的新makefile又出炉了。 只要make看到一个 ``.o`` 文件,它就会自动的把 ``.c`` 文件加在依赖关系中如果make找到一个 ``whatever.o`` ,那么 ``whatever.c`` 就会是 ``whatever.o`` 的依赖文件。并且 ``cc -c whatever.c`` 也会被推导出来于是我们的makefile再也不用写得这么复杂。我们的新makefile又出炉了。
.. code-block:: makefile .. code-block:: makefile
@ -178,7 +178,7 @@ GNU的make很强大它可以自动推导文件以及文件依赖关系后面
clean : clean :
rm edit $(objects) rm edit $(objects)
这种方法也就是make的“隐晦规则”。上面文件内容中 ``.PHONY`` 表示clean是个伪目标文件。 这种方法也就是make的“隐晦规则”。上面文件内容中 ``.PHONY`` 表示 ``clean`` 是个伪目标文件。
关于更为详细的“隐晦规则”和“伪目标文件”,我会在后续给你一一道来。 关于更为详细的“隐晦规则”和“伪目标文件”,我会在后续给你一一道来。
@ -223,7 +223,7 @@ GNU的make很强大它可以自动推导文件以及文件依赖关系后面
clean : clean :
-rm edit $(objects) -rm edit $(objects)
前面说过,.PHONY意思表示clean是一个“伪目标”。而在rm命令前面加了一个小减号的意思就是也许某些文件出现问题但不要管继续做后面的事。当然clean的规则不要放在文件的开头不然这就会变成make的默认目标相信谁也不愿意这样。不成文的规矩是——“clean从来都是放在文件的最后”。 前面说过, ``.PHONY`` 表示 ``clean`` 是一个“伪目标”。而在 ``rm`` 命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。当然, ``clean`` 的规则不要放在文件的开头不然这就会变成make的默认目标相信谁也不愿意这样。不成文的规矩是——“clean从来都是放在文件的最后”。
上面就是一个makefile的概貌也是makefile的基础下面还有很多makefile的相关细节准备好了吗准备好了就来。 上面就是一个makefile的概貌也是makefile的基础下面还有很多makefile的相关细节准备好了吗准备好了就来。
@ -232,7 +232,7 @@ Makefile里有什么
Makefile里主要包含了五个东西显式规则、隐晦规则、变量定义、文件指示和注释。 Makefile里主要包含了五个东西显式规则、隐晦规则、变量定义、文件指示和注释。
#. 显式规则。显式规则说明了如何生成一个或多个目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。 #. 显式规则。显式规则说明了如何生成一个或多个目标文件。这是由Makefile的书写者明显指出要生成的文件、文件的依赖文件和生成的命令。
#. 隐晦规则。由于我们的make有自动推导的功能所以隐晦的规则可以让我们比较简略地书写Makefile这是由make所支持的。 #. 隐晦规则。由于我们的make有自动推导的功能所以隐晦的规则可以让我们比较简略地书写Makefile这是由make所支持的。
#. 变量的定义。在Makefile中我们要定义一系列的变量变量一般都是字符串这个有点像你C语言中的宏当Makefile被执行时其中的变量都会被扩展到相应的引用位置上。 #. 变量的定义。在Makefile中我们要定义一系列的变量变量一般都是字符串这个有点像你C语言中的宏当Makefile被执行时其中的变量都会被扩展到相应的引用位置上。
#. 文件指示。其包括了三个部分一个是在一个Makefile中引用另一个Makefile就像C语言中的include一样另一个是指根据某些情况指定Makefile中的有效部分就像C语言中的预编译#if一样还有就是定义一个多行的命令。有关这一部分的内容我会在后续的部分中讲述。 #. 文件指示。其包括了三个部分一个是在一个Makefile中引用另一个Makefile就像C语言中的include一样另一个是指根据某些情况指定Makefile中的有效部分就像C语言中的预编译#if一样还有就是定义一个多行的命令。有关这一部分的内容我会在后续的部分中讲述。
@ -250,15 +250,15 @@ Makefile的文件名
引用其它的Makefile 引用其它的Makefile
------------------ ------------------
在Makefile使用include关键字可以把别的Makefile包含进来这很像C语言的#include被包含的文件会原模原样的放在当前文件的包含位置。include的语法是 在Makefile使用 ``include`` 关键字可以把别的Makefile包含进来这很像C语言的 ``#include`` ,被包含的文件会原模原样的放在当前文件的包含位置。 ``include`` 的语法是:
.. code-block:: makefile .. code-block:: makefile
include <filename>; include <filename>
filename可以是当前操作系统Shell的文件模式可以包含路径和通配符 ``filename`` 可以是当前操作系统Shell的文件模式可以包含路径和通配符
在include前面可以有一些空字符但是绝不能是 ``Tab`` 键开始。 ``include````<filename>;`` 可以用一个或多个空格隔开。举个例子你有这样几个Makefilea.mk、b.mk、c.mk还有一个文件叫foo.make以及一个变量 ``$(bar)`` ,其包含了 ``e.mk````f.mk`` ,那么,下面的语句: ``include`` 前面可以有一些空字符,但是绝不能是 ``Tab`` 键开始。 ``include````<filename>`` 可以用一个或多个空格隔开。举个例子你有这样几个Makefile ``a.mk`` ``b.mk`` ``c.mk`` ,还有一个文件叫 ``foo.make`` ,以及一个变量 ``$(bar)`` ,其包含了 ``e.mk````f.mk`` ,那么,下面的语句:
.. code-block:: makefile .. code-block:: makefile
@ -270,23 +270,23 @@ filename可以是当前操作系统Shell的文件模式可以包含路径和
include foo.make a.mk b.mk c.mk e.mk f.mk include foo.make a.mk b.mk c.mk e.mk f.mk
make命令开始时会找寻include所指出的其它Makefile并把其内容安置在当前的位置。就好像C/C++的#include指令一样。如果文件都没有指定绝对路径或是相对路径的话make会在当前目录下首先寻找如果当前目录下没有找到那么make还会在下面的几个目录下找 make命令开始时会找寻 ``include`` 所指出的其它Makefile并把其内容安置在当前的位置。就好像C/C++的 ``#include`` 指令一样。如果文件都没有指定绝对路径或是相对路径的话make会在当前目录下首先寻找如果当前目录下没有找到那么make还会在下面的几个目录下找
#. 如果make执行时``-I````--include-dir`` 参数那么make就会在这个参数所指定的目录下去寻找。 #. 如果make执行时``-I````--include-dir`` 参数那么make就会在这个参数所指定的目录下去寻找。
#. 如果目录<prefix>/include一般是/usr/local/bin或/usr/include存在的话make也会去找。 #. 如果目录 ``<prefix>/include`` (一般是: ``/usr/local/bin`` ``/usr/include`` 存在的话make也会去找。
如果有文件没有找到的话make会生成一条警告信息但不会马上出现致命错误。它会继续载入其它的文件一旦完成makefile的读取make会再重试这些没有找到或是不能读取的文件如果还是不行make才会出现一条致命信息。如果你想让make不理那些无法读取的文件而继续执行你可以在include前加一个减号“-”。如: 如果有文件没有找到的话make会生成一条警告信息但不会马上出现致命错误。它会继续载入其它的文件一旦完成makefile的读取make会再重试这些没有找到或是不能读取的文件如果还是不行make才会出现一条致命信息。如果你想让make不理那些无法读取的文件而继续执行你可以在include前加一个减号“-”。如:
.. code-block:: makefile .. code-block:: makefile
-include <filename>; -include <filename>
其表示无论include过程中出现什么错误都不要报错继续执行。和其它版本make兼容的相关命令是sinclude其作用和这一个是一样的。 其表示无论include过程中出现什么错误都不要报错继续执行。和其它版本make兼容的相关命令是sinclude其作用和这一个是一样的。
环境变量MAKEFILES 环境变量MAKEFILES
----------------- -----------------
如果你的当前环境中定义了环境变量MAKEFILES那么make会把这个变量中的值做一个类似于include的动作。这个变量中的值是其它的Makefile用空格分隔。只是它和include不同的是从这个环境变量中引入的Makefile的“目标”不会起作用如果环境变量中定义的文件发现错误make也会不理。 如果你的当前环境中定义了环境变量 ``MAKEFILES`` 那么make会把这个变量中的值做一个类似于 ``include`` 的动作。这个变量中的值是其它的Makefile用空格分隔。只是它和 ``include`` 不同的是从这个环境变量中引入的Makefile的“目标”不会起作用如果环境变量中定义的文件发现错误make也会不理。
但是在这里我还是建议不要使用这个环境变量因为只要这个变量一被定义那么当你使用make时所有的Makefile都会受到它的影响这绝不是你想看到的。在这里提这个事只是为了告诉大家也许有时候你的Makefile出现了怪事那么你可以看看当前环境中有没有定义这个变量。 但是在这里我还是建议不要使用这个环境变量因为只要这个变量一被定义那么当你使用make时所有的Makefile都会受到它的影响这绝不是你想看到的。在这里提这个事只是为了告诉大家也许有时候你的Makefile出现了怪事那么你可以看看当前环境中有没有定义这个变量。