Skip to content

Commit d73af1a

Browse files
authored
Update Introduction.rst (#51)
1 parent f5e4687 commit d73af1a

File tree

4 files changed

+62
-54
lines changed

4 files changed

+62
-54
lines changed

source/functions.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ shell函数也不像其它的函数。顾名思义,它的参数应该就是操
503503
504504
注意,这个函数会新生成一个Shell程序来执行命令,所以你要注意其运行性能,如果你的Makefile中
505505
有一些比较复杂的规则,并大量使用了这个函数,那么对于你的系统性能是有害的。特别是Makefile的
506-
隐晦的规则可能会让你的shell函数执行的次数比你想像的多得多
506+
隐式规则可能会让你的shell函数执行的次数比你想像的多得多
507507

508508
控制make的函数
509509
--------------

source/introduction.rst

+55-47
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,22 @@ makefile的规则
2222
.. code-block:: makefile
2323
2424
target ... : prerequisites ...
25-
command
25+
recipe
2626
...
2727
...
2828
2929
target
30-
可以是一个object file(目标文件),也可以是一个执行文件,还可以是一个标签(label)。对
30+
可以是一个object file(目标文件),也可以是一个可执行文件,还可以是一个标签(label)。对
3131
于标签这种特性,在后续的“伪目标”章节中会有叙述。
3232
prerequisites
33-
生成该target所依赖的文件和/或target
34-
command
35-
该target要执行的命令(任意的shell命令)
33+
生成该target所依赖的文件和/或target
34+
recipe
35+
该target要执行的命令(任意的shell命令)
3636

3737
这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,
3838
其生成规则定义在command中。说白一点就是说::
3939

40-
prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行
40+
prerequisites中如果有一个以上的文件比target文件要新的话,recipe所定义的命令就会被执行
4141

4242
这就是makefile的规则,也就是makefile中最核心的内容。
4343

@@ -48,7 +48,7 @@ command
4848
一个示例
4949
--------
5050

51-
正如前面所说,如果一个工程有3个头文件和8个c文件,为了完成前面所述的那三个规则,我们的makefile
51+
正如前面所说,如果一个工程有3个头文件和8个C文件,为了完成前面所述的那三个规则,我们的makefile
5252
应该是下面的这个样子的。
5353

5454
.. code-block:: makefile
@@ -80,20 +80,20 @@ command
8080
8181
反斜杠( ``\`` )是换行符的意思。这样比较便于makefile的阅读。我们可以把这个内容保存在名字
8282
为“makefile”或“Makefile”的文件中,然后在该目录下直接输入命令 ``make`` 就可以生成执行文
83-
件edit。如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下 ``make clean`` 就
83+
件edit。如果要删除可执行文件和所有的中间目标文件,那么,只要简单地执行一下 ``make clean`` 就
8484
可以了。
8585

86-
在这个makefile中,目标文件(target)包含:执行文件edit和中间目标文件( ``*.o`` ),依赖文
86+
在这个makefile中,目标文件(target)包含:可执行文件edit和中间目标文件( ``*.o`` ),依赖文
8787
件(prerequisites)就是冒号后面的那些 ``.c`` 文件和 ``.h`` 文件。每一个 ``.o`` 文件都有
88-
一组依赖文件,而这些 ``.o`` 文件又是执行文件 ``edit`` 的依赖文件。依赖关系的实质就是说明了目
88+
一组依赖文件,而这些 ``.o`` 文件又是可执行文件 ``edit`` 的依赖文件。依赖关系的实质就是说明了目
8989
标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。
9090

91-
在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个 ``Tab`` 键
91+
在定义好依赖关系后,后续的recipe行定义了如何生成目标文件的操作系统命令,一定要以一个 ``Tab`` 键
9292
作为开头。记住,make并不管命令是怎么工作的,他只管执行所定义的命令。make会比较targets文件
9393
和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或
9494
者target不存在的话,那么,make就会执行后续定义的命令。
9595

96-
这里要说明一点的是, ``clean`` 不是一个文件,它只不过是一个动作名字,有点像c语言中的label一
96+
这里要说明一点的是, ``clean`` 不是一个文件,它只不过是一个动作名字,有点像C语言中的label一
9797
样,其冒号后什么也没有,那么,make就不会自动去找它的依赖性,也就不会自动执行其后所定义的命令。
9898
要执行其后的命令,就要在make命令后明显得指出这个label的名字。这样的方法非常有用,我们可以在一
9999
个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。
@@ -110,8 +110,8 @@ make是如何工作的
110110
文件新,那么,他就会执行后面所定义的命令来生成 ``edit`` 这个文件。
111111
#. 如果 ``edit`` 所依赖的 ``.o`` 文件也不存在,那么make会在当前文件中找目标为 ``.o`` 文件
112112
的依赖性,如果找到则再根据那一个规则生成 ``.o`` 文件。(这有点像一个堆栈的过程)
113-
#. 当然,你的C文件和H文件是存在的啦,于是make会生成 ``.o`` 文件,然后再用 ``.o`` 文件生
114-
成make的终极任务,也就是执行文件 ``edit`` 了。
113+
#. 当然,你的C文件和头文件是存在的啦,于是make会生成 ``.o`` 文件,然后再用 ``.o`` 文件生
114+
成make的终极任务,也就是可执行文件 ``edit`` 了。
115115

116116
这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在
117117
找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所
@@ -222,13 +222,13 @@ GNU的make很强大,它可以自动推导文件以及文件依赖关系后面
222222
clean :
223223
rm edit $(objects)
224224
225-
这种方法,也就是make的“隐晦规则”。上面文件内容中, ``.PHONY`` 表示 ``clean`` 是个伪目标
225+
这种方法就是make的“隐式规则”。上面文件内容中, ``.PHONY`` 表示 ``clean`` 是个伪目标
226226
文件。
227227

228-
关于更为详细的“隐晦规则”和“伪目标文件”,我会在后续给你一一道来。
228+
关于更为详细的“隐式规则”和“伪目标文件”,我会在后续给你一一道来。
229229

230-
另类风格的makefiles
231-
-------------------
230+
makefile的另一种风格
231+
--------------------
232232

233233
既然我们的make可以自动推导命令,那么我看到那堆 ``.o`` 和 ``.h`` 的依赖就有点不爽,那么多的
234234
重复的 ``.h`` ,能不能把其收拢起来,好吧,没有问题,这个对于make来说很容易,谁叫它提供了自动
@@ -250,14 +250,17 @@ GNU的make很强大,它可以自动推导文件以及文件依赖关系后面
250250
clean :
251251
rm edit $(objects)
252252
253-
这种风格,让我们的makefile变得很简单,但我们的文件依赖关系就显得有点凌乱了。鱼和熊掌不可兼得。
253+
这里 ``defs.h`` 是所有目标文件的依赖文件, ``command.h`` 和 ``buffer.h`` 是对应目标文件的
254+
依赖文件。
255+
256+
这种风格能让我们的makefile变得很短,但我们的文件依赖关系就显得有点凌乱了。鱼和熊掌不可兼得。
254257
还看你的喜好了。我是不喜欢这种风格的,一是文件的依赖关系看不清楚,二是如果文件一多,要加入几个
255258
新的 ``.o`` 文件,那就理不清楚了。
256259

257-
清空目标文件的规则
260+
清空目录的规则
258261
------------------
259262

260-
每个Makefile中都应该写一个清空目标文件( ``.o`` 和执行文件)的规则,这不仅便于重编译,也很
263+
每个Makefile中都应该写一个清空目标文件( ``.o`` )和可执行文件的规则,这不仅便于重编译,也很
261264
利于保持文件的清洁。这是一个“修养”(呵呵,还记得我的《编程修养》吗)。一般的风格都是:
262265

263266
.. code-block:: makefile
@@ -284,15 +287,15 @@ GNU的make很强大,它可以自动推导文件以及文件依赖关系后面
284287
Makefile里有什么?
285288
------------------
286289

287-
Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释
290+
Makefile里主要包含了五个东西:显式规则、隐式规则、变量定义、指令和注释
288291

289292
#. 显式规则。显式规则说明了如何生成一个或多个目标文件。这是由Makefile的书写者明显指出要生成的
290293
文件、文件的依赖文件和生成的命令。
291-
#. 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较简略地书写
292-
Makefile,这是由make所支持的。
294+
#. 隐式规则。由于我们的make有自动推导的功能,所以隐式规则可以让我们比较简略地书写Makefile,
295+
这是由make所支持的。
293296
#. 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点像你C语言中的
294297
宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
295-
#. 文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中
298+
#. 指令。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中
296299
的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一
297300
样;还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲述。
298301
#. 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用 ``#`` 字符,这个就
@@ -304,32 +307,33 @@ Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定
304307
Makefile的文件名
305308
----------------
306309

307-
默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、
308-
“makefile”、“Makefile的文件,找到了解释这个文件。在这三个文件名中,最好使用Makefile
309-
这个文件名,因为,这个文件名第一个字符为大写,这样有一种显目的感觉。最好不要用GNUmakefile”,
310-
这个文件是GNU的make识别的。有另外一些make只对全小写的“makefile”文件名敏感,但是基本上来说,
311-
大多数的make都支持“makefile”和“Makefile这两种默认文件名。
310+
默认的情况下,make命令会在当前目录下按顺序寻找文件名为 ``GNUmakefile`` 、 ``makefile`` 和
311+
``Makefile`` 的文件。在这三个文件名中,最好使用 ``Makefile`` 这个文件名,因为这个文件名在
312+
排序上靠近其它比较重要的文件,比如 ``README``。最好不要用 ``GNUmakefile``,因为这个文件名
313+
只能由GNU ``make`` ,其它版本的 ``make`` 无法识别,但是基本上来说,大多数的 ``make`` 都支持
314+
``makefile`` 和 ``Makefile`` 这两种默认文件名。
312315

313-
当然,你可以使用别的文件名来书写Makefile,比如:“Make.Linux”,“Make.Solaris”
314-
,“Make.AIX”等,如果要指定特定的Makefile,你可以使用make的 ``-f`` 和 ``--file`` 参数,
315-
如: ``make -f Make.Linux`` 或 ``make --file Make.AIX`` 。
316+
当然,你可以使用别的文件名来书写Makefile,比如:“Make.Solaris”,“Make.Linux”
317+
等,如果要指定特定的Makefile,你可以使用make的 ``-f`` 或 ``--file`` 参数,如:
318+
``make -f Make.Solaris`` 或 ``make --file Make.Linux`` 。如果你使用多条 ``-f`` 或 ``--file``
319+
参数,你可以指定多个makefile。
316320

317-
引用其它的Makefile
321+
包含其它Makefile
318322
------------------
319323

320-
在Makefile使用 ``include`` 关键字可以把别的Makefile包含进来,这很像C语言的
324+
在Makefile使用 ``include`` 指令可以把别的Makefile包含进来,这很像C语言的
321325
``#include`` ,被包含的文件会原模原样的放在当前文件的包含位置。 ``include`` 的语法是:
322326

323327
.. code-block:: makefile
324328
325-
include <filename>
329+
include <filenames>...
326330
327-
``filename`` 可以是当前操作系统Shell的文件模式(可以包含路径和通配符)。
331+
``<filenames>`` 可以是当前操作系统Shell的文件模式(可以包含路径和通配符)。
328332

329333
在 ``include`` 前面可以有一些空字符,但是绝不能是 ``Tab`` 键开始。 ``include`` 和
330-
``<filename>`` 可以用一个或多个空格隔开。举个例子,你有这样几个Makefile: ``a.mk`` 、
334+
``<filenames>`` 可以用一个或多个空格隔开。举个例子,你有这样几个Makefile: ``a.mk`` 、
331335
``b.mk`` 、 ``c.mk`` ,还有一个文件叫 ``foo.make`` ,以及一个变量 ``$(bar)`` ,其包含
332-
了 ``e.mk`` 和 ``f.mk`` ,那么,下面的语句:
336+
了 ``bish`` 和 ``bash`` ,那么,下面的语句:
333337

334338
.. code-block:: makefile
335339
@@ -339,16 +343,20 @@ Makefile的文件名
339343

340344
.. code-block:: makefile
341345
342-
include foo.make a.mk b.mk c.mk e.mk f.mk
346+
include foo.make a.mk b.mk c.mk bish bash
343347
344348
make命令开始时,会找寻 ``include`` 所指出的其它Makefile,并把其内容安置在当前的位置。就好
345349
像C/C++的 ``#include`` 指令一样。如果文件都没有指定绝对路径或是相对路径的话,make会在当前目
346350
录下首先寻找,如果当前目录下没有找到,那么,make还会在下面的几个目录下找:
347351

348352
#. 如果make执行时,有 ``-I`` 或 ``--include-dir`` 参数,那么make就会在这个参数所指定的目
349353
录下去寻找。
350-
#. 如果目录 ``<prefix>/include`` (一般是: ``/usr/local/bin`` 或
351-
``/usr/include`` )存在的话,make也会去找。
354+
#. 接下来按顺序寻找目录 ``<prefix>/include`` (一般是 ``/usr/local/bin`` )、
355+
``/usr/gnu/include`` 、 ``/usr/local/include`` 、 ``/usr/include`` 。
356+
357+
环境变量 ``.INCLUDE_DIRS`` 包含当前 make 会寻找的目录列表。你应当避免使用命令行参数
358+
``-I`` 来寻找以上这些默认目录,否则会使得 ``make`` “忘掉”所有已经设定的包含目录,包括默认
359+
目录。
352360

353361
如果有文件没有找到的话,make会生成一条警告信息,但不会马上出现致命错误。它会继续载入其它的
354362
文件,一旦完成makefile的读取,make会再重试这些没有找到,或是不能读取的文件,如果还是
@@ -357,15 +365,15 @@ make命令开始时,会找寻 ``include`` 所指出的其它Makefile,并把
357365

358366
.. code-block:: makefile
359367
360-
-include <filename>
368+
-include <filenames>...
361369
362-
其表示,无论include过程中出现什么错误,都不要报错继续执行。和其它版本make兼容的相关命令
363-
是sinclude,其作用和这一个是一样的
370+
其表示,无论include过程中出现什么错误,都不要报错继续执行。如果要和其它版本 ``make`` 兼容,
371+
可以使用 ``sinclude`` 代替 ``-include``
364372

365373
环境变量MAKEFILES
366374
-----------------
367375

368-
如果你的当前环境中定义了环境变量 ``MAKEFILES`` ,那么,make会把这个变量中的值做一个类似于
376+
如果你的当前环境中定义了环境变量 ``MAKEFILES`` ,那么make会把这个变量中的值做一个类似于
369377
``include`` 的动作。这个变量中的值是其它的Makefile,用空格分隔。只是,它和 ``include`` 不
370378
同的是,从这个环境变量中引入的Makefile的“目标”不会起作用,如果环境变量中定义的文件发现
371379
错误,make也会不理。
@@ -382,7 +390,7 @@ GNU的make工作时的执行步骤如下:(想来其它的make也是类似)
382390
#. 读入所有的Makefile。
383391
#. 读入被include的其它Makefile。
384392
#. 初始化文件中的变量。
385-
#. 推导隐晦规则,并分析所有规则。
393+
#. 推导隐式规则,并分析所有规则。
386394
#. 为所有的目标文件创建依赖关系链。
387395
#. 根据依赖关系,决定哪些目标要重新生成。
388396
#. 执行生成命令。

source/overview.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ makefile带来的好处就是——“自动化编译”,一旦写好,只需
3030

3131
在此,我想多说关于程序编译的一些规范和方法。一般来说,无论是C还是C++,首先要把源文件编译成中间
3232
代码文件,在Windows下也就是 ``.obj`` 文件,UNIX下是 ``.o`` 文件,即Object File,这个动
33-
作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。
33+
作叫做编译(compile)。然后再把大量的Object File合成可执行文件,这个动作叫作链接(link)。
3434

3535
编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文
3636
件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就
@@ -44,7 +44,7 @@ makefile带来的好处就是——“自动化编译”,一旦写好,只需
4444
叫“库文件”(Library File),也就是 ``.lib`` 文件,在UNIX下,是Archive File,也就是
4545
``.a`` 文件。
4646

47-
总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程
47+
总结一下,源文件首先会生成中间目标文件,再由中间目标文件生成可执行文件。在编译时,编译器只检测程
4848
序语法和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。
4949
而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码
5050
(Linker Error),在VC下,这种错误一般是: ``Link 2001错误`` ,意思说是说,链接器未能找到

source/variables.rst

+4-4
Original file line numberDiff line numberDiff line change
@@ -346,11 +346,11 @@ dir这个变量的值是“/foo/bar”,后面还跟了4个空格,如果我
346346
由于前次的赋值符是 ``=`` ,所以 ``+=`` 也会以 ``=`` 来做为赋值,那么岂不会发生变量的递补归
347347
定义,这是很不好的,所以make会自动为我们解决这个问题,我们不必担心这个问题。
348348

349-
override 指示符
349+
override 指令
350350
---------------
351351

352352
如果有变量是通常make的命令行参数设置的,那么Makefile中对这个变量的赋值会被忽略。如果你想
353-
在Makefile中设置这类参数的值,那么,你可以使用“override”指示符。其语法是::
353+
在Makefile中设置这类参数的值,那么,你可以使用“override”指令。其语法是::
354354

355355
override <variable>; = <value>;
356356

@@ -360,7 +360,7 @@ override 指示符
360360

361361
override <variable>; += <more text>;
362362

363-
对于多行的变量定义,我们用define指示符,在define指示符前,也同样可以使用override指示符
363+
对于多行的变量定义,我们用define指令,在define指令前,也同样可以使用override指令
364364
如::
365365

366366
override define foo
@@ -373,7 +373,7 @@ override 指示符
373373
还有一种设置变量值的方法是使用define关键字。使用define关键字设置变量的值可以有换行,这有利于
374374
定义一系列的命令(前面我们讲过“命令包”的技术就是利用这个关键字)。
375375

376-
define指示符后面跟的是变量的名字,而重起一行定义变量的值,定义是以endef 关键字结束。其工作方
376+
define指令后面跟的是变量的名字,而重起一行定义变量的值,定义是以endef 关键字结束。其工作方
377377
式和“=”操作符一样。变量的值可以包含函数、命令、文字,或是其它变量。因为命令需要以[Tab]键开头,
378378
所以如果你用define定义的命令变量中没有以 ``Tab`` 键开头,那么make 就不会把其认为是命令。
379379

0 commit comments

Comments
 (0)