GNU Make 手册第二章节

2 An Introduction to Makefiles

You need a file called a makefile to tell make what to do. Most often, the makefile tells make how to compile and link a program.

您需要一个名为 makefile 的文件来告诉 make 做什么。大多数情况下,makefile 告诉 make 如何编译和链接程序。

In this chapter, we will discuss a simple makefile that describes how to compile and link a text editor which consists of eight C source files and three header files.
The makefile can also tell make how to run miscellaneous commands when explicitly asked (for example, to remove certain files as a clean-up operation).

在本章中,我们将讨论一个简单的makefile,它描述了如何编译和链接一个包含八个C源文件和三个头文件的文本编辑器。
makefile 还可以告诉 make 在显式请求时如何运行其他命令(例如,作为清理操作删除某些文件)

To see a more complex example of a makefile, see Appendix C [Complex Makefile], page 177.

查看更复杂的makefile示例, 参见附录C [Complex Makefile],第177页。

When make recompiles the editor, each changed C source file must be recompiled.
If a header file has changed, each C source file that includes the header file must be recompiled to be safe.
Each compilation produces an object file corresponding to the source file.
Finally, if any source file has been recompiled, all the object files, whether newly made or saved from previous compilations,
must be linked together to produce the new executable editor.

当make重新编译 editor 时,必须重新编译每个更改过的C源文件。
如果头文件发生了更改,为了安全起见,必须重新编译包含头文件的每个C源文件。
每次编译都会产生与源文件对应的目标文件。
最后,源文件都被重新编译,那么所有的目标文件,无论是新创建的还是之前编译中保存的,必须链接在一起以生成新的可执行editor

2.1 What a Rule Looks Like

A simple makefile consists of “rules” with the following shape:

一个简单的 makefile 由类似下面的“规则”组成:

target ... : prerequisites ...
          recipe
          ...
          ...

A target is usually the name of a file that is generated by a program; examples of targets are executable or object files.
A target can also be the name of an action to carry out, such as ‘clean’ (see Section 4.5 [Phony Targets], page 29).

target (目标)通常是程序生成的文件的名称。 target 的示例是可执行文件或对象文件。
target 也可以是要执行的操作的名称,例如“clean”(请参见第4.5节,[Phony Targets],第29页)。

A prerequisite is a file that is used as input to create the target. A target often depends on several files.

prerequisite (前提条件)是将用作创建 target 的输入文件。 target 通常依赖多个文件。

A recipe is an action that make carries out.
A recipe may have more than one command, either on the same line or each on its own line.
Please note: you need to put a tab character at the beginning of every recipe line! This is an obscurity that catches the unwary.
If you prefer to prefix your recipes with a character other than tab, you can set the .
RECIPEPREFIX variable to an alternate character (see Section 6.14 [Special Variables], page 73).

recipe 是要执行的动作
recipe 可能在同一行或在自己的行中具有多个命令。
请注意:你需要在每一行的开头放一个制表符。这是一个模糊的地方,需要引起人们的注意。
如果您想为 recipe 加上制表符以外的其他字符,也可以设置。
将RECIPEPREFIX变量转换为备用字符(请参见第6.14节[特殊变量],第73页)。

Usually a recipe is in a rule with prerequisites and serves to create a target file if any of the prerequisites change.
However, the rule that specifies a recipe for the target need not have prerequisites.
For example, the rule containing the delete command associated with the target ‘clean’ does not have prerequisites.

通常 recipe 位于 prerequisites 的规则中, 任何 prerequisites 的改变 都将重新创建目标文件
但是,为 target 指定 recipe 的规则可以没有 prerequisites。
例如,target 为 “clean” 相关联的 delete 命令的规则就没有 prerequisites。

A rule, then, explains how and when to remake certain files which are the targets of the particular rule.
make carries out the recipe on the prerequisites to create or update the target.
A rule can also explain how and when to carry out an action. See Chapter 4 [Writing Rules], page 21.

规则指定了如何以及何时重新生成特定规则的目标文件。
make 命令在 prerequisites 上执行 recipe 以创建或更新 target (目标)。
规则还可以指定如何以及何时执行操作。 请参阅第4章[编写规则],第21页。

A makefile may contain other text besides rules, but a simple makefile need only contain rules.
Rules may look somewhat more complicated than shown in this template, but all fit the pattern more or less.

一个makefile可能包含除规则之外的其他文本,但是一个简单的makefile只需要包含规则。
实际的规则看起来可能比这个模板中显示的要复杂一些,但大体类似。

2.2 A Simple Makefile

Here is a straightforward makefile that describes the way an executable file called edit depends on eight object files which,
in turn, depend on eight C source and three header files.

下面是一个简单的makefile,描述了一个名为edit的可执行文件如何依赖于8个目标文件,而这些目标文件又依赖于8个C源文件和3个头文件。

In this example, all the C files include defs.h, but only those defining editing commands include command.h,
and only low level files that change the editor buffer include buffer.h.

在本例中,所有C文件都包含 defs.h,但只有那些定义编辑命令的文件才包含command.h,
只有更改编辑器缓冲区的低级文件才包含buffer.h。

	edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o
				cc -o edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o
							
	main.o : main.c defs.h
			cc -c main.c
	kbd.o : kbd.c defs.h command.h
			cc -c kbd.c
	command.o : command.c defs.h command.h
			cc -c command.c
	display.o : display.c defs.h buffer.h
			cc -c display.c
	insert.o : insert.c defs.h buffer.h
			cc -c insert.c
	search.o : search.c defs.h buffer.h
			cc -c search.c
	files.o : files.c defs.h buffer.h command.h
			cc -c files.c
	utils.o : utils.c defs.h
			cc -c utils.c
	clean :
			rm edit main.o kbd.o command.o display.o \
				insert.o search.o files.o utils.o

We split each long line into two lines using backslash/newline; this is like using one long line,
but is easier to read. See Section 3.1.1 [Splitting Long Lines], page 12.

我们使用反斜杠/换行符将每条长线分成两行;这与使用一条长线是一样的,但更容易阅读。
参见第12页第3.1.1节[分割长线]。

To use this makefile to create the executable file called edit, type:
make
To use this makefile to delete the executable file and all the object files from the directory, type:
make clean

要使用这个makefile创建名为edit的可执行文件,输入 make
要使用这个makefile删除可执行文件和目录中的所有目标文件,输入: make clean

In the example makefile, the targets include the executable file ‘edit’, and the object files ‘main.o’ and ‘kbd.o’.
The prerequisites are files such as ‘main.c’ and ‘defs.h’.
In fact, each ‘.o’ file is both a target and a prerequisite.
Recipes include ‘cc -c main.c’ and ‘cc -c kbd.c’.

在示例makefile中,target(目标) 包括可执行文件“edit”,以及对象文件“main.o”和“kbd.o”等。
prerequisites (前提条件) 是诸如“ main.c”和“ defs.h”之类的文件。
实际上,每个“ .o”文件既是 target (目标),也是 prerequisites(前提)。
Recipes (配方) 包括“ cc -c main.c”和“ cc -c kbd.c”。

When a target is a file, it needs to be recompiled or relinked if any of its prerequisites change.
In addition, any prerequisites that are themselves automatically generated should be updated first.
In this example, edit depends on each of the eight object files;
the object file main.o depends on the source file main.c and on the header file defs.h.

当 target (目标) 是文件时,如果其任何先决条件发生更改,都需要重新编译或重新连接。
此外,应该首先更新本身自动生成的任何先决条件。
在本例中,edit 依赖于八个对象文件;
而对象文件main.o 又依赖于源文件main.c和头文件defs.h。

A recipe may follow each line that contains a target and prerequisites.
These recipes say how to update the target file.
A tab character (or whatever character is specified by the .RECIPEPREFIX variable; see Section 6.14 [Special Variables], page 73)
must come at the beginning of every line in the recipe to distinguish recipes from other lines in the makefile.
(Bear in mind that make does not know anything about how the recipes work.
It is up to you to supply recipes that will update the target file properly.
All make does is execute the recipe you have specified when the target file needs to be updated.)

recipe (配方) 可以在包含 target (目标) 和 prerequisites (先决条件)的每一行后面。
这些 recipes (配方) 说明了如何更新 target (目标) 文件。
制表符(或.RECIPEPREFIX变量指定的任何字符;请参见第73页的6.14节[特殊变量])
必须在 recipes (配方) 每一行的开头,以将 recipes (配方) 与makefile中的其他行区分开。
(请注意,make并不知道这些 recipes (配方) 是如何运作的。由您决定提供可以正确更新 target (目标) 文件的 recipes (配方)。
所有要做的工作都是在需要更新 target (目标)文件时执行指定的 recipes (配方) 。)

The target ‘clean’ is not a file, but merely the name of an action.
Since you normally do not want to carry out the actions in this rule, ‘clean’ is not a prerequisite of any other rule.
Consequently, make never does anything with it unless you tell it specifically.
Note that this rule not only is not a prerequisite, it also does not have any prerequisites,
so the only purpose of the rule is to run the specified recipe.
Targets that do not refer to files but are just actions are called phony targets.
See Section 4.5 [Phony Targets], page 29, for information about this kind of target.
See Section 5.5 [Errors in Recipes], page 49, to see how to cause make to ignore errors from rm or any other command.

目标 “clean” 不是一个文件,而是一个操作的名称。
由于您通常不希望在规则中实现此操作,所以 “clean” 不是任何其他规则的 prerequisite (先决条件)。
因此,除非特别说明,否则make绝对不会对其进行任何操作。
请注意,此规则不仅不是先决条件,也没有任何先决条件,因此该规则的唯一目的是运行指定的recipes (配方)。
不引用文件但只是操作的 target (目标) 称为假目标。有关此类目标的信息,请参见第4.5节,[Phony目标],第29页。
请参见第5.5页的[5.5节中的错误],以了解如何使make忽略 rm 或任何其他命令的错误。

2.3 A How make Processes a Makefile //make如何处理makefile

By default, make starts with the first target (not targets whose names start with ‘.’). This is called the default goal.
You can override this behavior using the command line (see Section 9.2 [Arguments to Specify the Goals], page 99)
or with the .DEFAULT_GOAL special variable (see Section 6.14 [Other Special Variables], page 73).

默认情况下,make从第一个target (目标)开始(而不是名称以“.”开头的 target (目标))。这称为默认目标。
您可以使用命令行覆盖此行为(请参见第9.2节“指定目标的参数”,第99页)
或带有.DEFAULT_GOAL特殊变量(请参见第6.14节[其他特殊变量],第73页)。

In the simple example of the previous section, the default goal is to update the executable program edit; therefore, we put that rule first.
Thus, when you give the command:
make

在上一部分的简单示例中,默认 goal 是更新可执行程序 edit。 因此,我们将该规则放在首位。
因此,当您发出命令时:make

make reads the makefile in the current directory and begins by processing the first rule.
In the example, this rule is for relinking edit; but before make can fully process this rule,
it must process the rules for the files that edit depends on, which in this case are the object files.
Each of these files is processed according to its own rule. These rules say to update each ‘.o’ file by compiling its source file.
The recompilation must be done if the source file, or any of the header files named as prerequisites,
is more recent than the object file, or if the object file does not exist.

make读取当前目录中的makefile并从处理第一条规则开始。
在此示例中,此规则用于重新链接 edit。
但是在make可以完全处理此规则之前,它必须处理 edit 所依赖的文件的规则,在本例中是对象文件。
这些文件中的每一个都按照自己的规则进行处理。这些规则规定通过编译源文件来更新每个“.o”文件。
如果源文件或作为 prerequisites (先决条件) 命名的任何头文件,比对象文件修改时间更新,或者对象文件不存在,将重新编译。

The other rules are processed because their targets appear as prerequisites of the goal.
If some other rule is not depended on by the goal (or anything it depends on, etc.),
that rule is not processed, unless you tell make to do so (with a command such as make clean).

make 处理其他规则是因为它们的 target 也是其他 target 的 prerequisites (先决条件)。
如果目标(goal)(或它所依赖的任何东西)不依赖于其他规则,那么除非您告诉make这样做(例如 make clean命令),否则 make 不会处理该规则。

Before recompiling an object file, make considers updating its prerequisites, the source file and header files.
This makefile does not specify anything to be done for them—the ‘.c’ and ‘.h’ files are not the targets of any rules—so make does nothing for these files.
But make would update automatically generated C programs, such as those made by Bison or Yacc, by their own rules at this time.

在重新编译Object文件之前,make 会先更新其 prerequisites (先决条件)的源文件和头文件。
本例中的 makefile 并没有为它们指定要执行的任何操作——“.c”和“.h”文件不是任何规则的目标——因此make不会对这些文件执行任何操作。
但是 make 会根据它们自己的规则来更新自动生成的C程序,例如 BisonYacc 生成的C程序。

After recompiling whichever object files need it, make decides whether to relink edit.
This must be done if the file edit does not exist, or if any of the object files are newer than it.
If an object file was just recompiled, it is now newer than edit, so edit is relinked.

重新编译所需的 Object 文件后,make决定是否重新链接 edit 。

Thus, if we change the file insert.c and run make, make will compile that file to update insert.o, and then link edit.
If we change the file command.h and run make, make will recompile the object files kbd.o, command.o and files.o and then link the file edit.

因此,如果我们更改文件insert.c并运行make,make将编译该文件以更新insert.o,然后链接edit。
如果更改文件command.h并运行make,make将重新编译目标文件kbd.ocommand.ofiles.o,然后链接文件edit。

2.4 Variables Make Makefiles Simpler //变量使Makefiles变得简单

In our example, we had to list all the object files twice in the rule for edit (repeated here):

在我们的示例中,我们必须在 edit 规则中列出所有目标文件两次(此处重复):

edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o
		cc -o edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o

Such duplication is error-prone;
if a new object file is added to the system, we might add it to one list and forget the other.
We can eliminate the risk and simplify the makefile by using a variable.
Variables allow a text string to be defined once and substituted in multiple places later (see Chapter 6 [How to Use Variables], page 59).

这种重复很容易出错;
如果一个新的目标文件被添加到系统中,我们可能会把它添加到一个列表中而忘记另一个。
我们可以通过使用变量来消除风险并简化makefile。
变量允许一次定义文本字符串,之后在多个地方替换(参见第6章[如何使用变量],第59页)。

It is standard practice for every makefile to have a variable named objects, OBJECTS, objs, OBJS, obj, or OBJ which is a list of all object file names.
We would define such a variable objects with a line like this in the makefile:

每个 makefile 都有一个名为 objects 的变量,这是一种标准实践,OBJECTS,objs OBJS, obj, 或 OBJ代表所有对象文件名的列表。
我们将在makefile中定义这样一个变量对象,如下所示:

objects = main.o kbd.o command.o display.o \
			insert.o search.o files.o utils.o

Then, each place we want to put a list of the object file names, we can substitute the variable’s value by writing ‘$(objects)’ (see Chapter 6 [How to Use Variables], page 59).
Here is how the complete simple makefile looks when you use a variable for the object files:

然后,在每个我们要放置目标文件名列表的地方,我们都可以通过编写“ $(objects)”来替换变量的值(请参见第6章[如何使用变量],第59页)。
当你为目标文件使用变量时,makefile看起来是这样的:

objects = main.o kbd.o command.o display.o \
			insert.o search.o files.o utils.o
			
edit : $(objects)
		cc -o edit $(objects)
main.o : main.c defs.h
		cc -c main.c
kbd.o : kbd.c defs.h command.h
		cc -c kbd.c
command.o : command.c defs.h command.h
		cc -c command.c
display.o : display.c defs.h buffer.h
		cc -c display.c
insert.o : insert.c defs.h buffer.h
		cc -c insert.c
search.o : search.c defs.h buffer.h
		cc -c search.c
files.o : files.c defs.h buffer.h command.h
		cc -c files.c
utils.o : utils.c defs.h
		cc -c utils.c
clean :
		rm edit $(objects)

2.5 Letting make Deduce the Recipes //简化 make 的 Recipes

It is not necessary to spell out the recipes for compiling the individual C source files, because make can figure them out:
it has an implicit rule for updating a ‘.o’ file from a correspondingly named ‘.c’ file using a ‘cc -c’ command.
For example, it will use the recipe ‘cc -c main.c -o main.o’ to compile main.c into main.o.
We can therefore omit the recipes from the rules for the object files. See Chapter 10 [Using Implicit Rules], page 111.

无需拼写recipes (配方)来编译单个C源文件,因为make可以弄清楚它们:
它有一个隐式规则,可以使用“cc-c”命令从相应名称的“.c”文件更新“.o”文件。
例如,它将使用recipes (配方) “ cc -c main.c -o main.o” 将 main.c 编译为 main.o。
因此,我们可以省略 object 文件规则中的 recipes (配方)。参见第10章[使用隐式规则],第111页。

When a ‘.c’ file is used automatically in this way, it is also automatically added to the list of prerequisites.
We can therefore omit the ‘.c’ files from the prerequisites, provided we omit the recipe.

当以这种方式自动使用“.c”文件时,它也会自动添加到 prerequisites (先决条件) 列表中。
因此,我们可以从 prerequisites (前提条件)中省略“.c”文件,前提是我们省略了recipes (配方)。

Here is the entire example, with both of these changes, and a variable objects as suggested above:

以下是完整的示例,其中包含所有这些更改以及上面建议的变量对象:

objects = main.o kbd.o command.o display.o \
		insert.o search.o files.o utils.o
		
edit : $(objects)
		cc -o edit $(objects)
		
main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs.h buffer.h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils.o : defs.h

.PHONY : clean
clean :
		rm edit $(objects)

This is how we would write the makefile in actual practice.
(The complications associated with ‘clean’ are described elsewhere. See Section 4.5 [Phony Targets], page 29, and Section 5.5 [Errors in Recipes], page 49.)

这就是我们在实际操作中编写 makefile 的方式。
(与“clean”相关的复杂性在其他地方进行了说明。请参见第29页的第4.5节[伪装目标]和第49页的5.5节[Recipes错误]。)

Because implicit rules are so convenient, they are important. You will see them used frequently.

因为隐式规则非常方便,所以它们很重要。 您将看到它们经常被使用。

2.6 Another Style of Makefile // 另一种风格的 Makefile

When the objects of a makefile are created only by implicit rules, an alternative style of makefile is possible.
In this style of makefile, you group entries by their prerequisites instead of by their targets. Here is what one looks like:

makefileobjects 仅由隐式规则创建时,可以使用另一种makefile风格。
这种风格的 makefile ,是按条目的 prerequisites (先决条件)而不是 targets(目标)将它们分组。
大概类似下面这样:

objects = main.o kbd.o command.o display.o \
		insert.o search.o files.o utils.o
		
edit : $(objects)
		cc -o edit $(objects)
		
$(objects) : defs.h
kbd.o command.o files.o : command.h
display.o insert.o search.o files.o : buffer.h

Here defs.h is given as a prerequisite of all the object files;
command.h and buffer.h are prerequisites of the specific object files listed for them.

defs.h 是所有 object 文件的先决条件(prerequisite)。
command.hbuffer.h 是为其列出的特定对象文件的先决条件(prerequisites )。

Whether this is better is a matter of taste:
it is more compact, but some people dislike it because they find it clearer to put all the information about each target in one place.

这是否更好仁者见仁智者见智:
它更紧凑,但也有人不喜欢它,因为将每个目标的所有信息都放在一个地方更加清晰。

2.7 Rules for Cleaning the Directory //清理目录的规则

Compiling a program is not the only thing you might want to write rules for.
Makefiles commonly tell how to do a few other things besides compiling a program:
for example, how to delete all the object files and executables so that the directory is ‘clean’.

用写的规则(rule)编译一个程序并不是你唯一要做的事情。
Makefile通常会告诉您除编译程序外还要做些其他事情:
例如,如何删除所有目标文件和可执行文件,以便目录为“干净”。

Here is how we could write a make rule for cleaning our example editor:

下面是如何编写make规则来清理示例中的 editor:

clean:
		rm edit $(objects)

In practice, we might want to write the rule in a somewhat more complicated manner to handle unanticipated situations.
We would do this:

在实践中,我们可能希望以更复杂的方式编写规则来处理意外情况。
我们会这样做:

.PHONY : clean
clean :
		-rm edit $(objects)

This prevents make from getting confused by an actual file called clean and causes it to continue in spite of errors from rm.
(See Section 4.5 [Phony Targets], page 29, and Section 5.5 [Errors in Recipes], page 49.)

这可以防止make被一个名为clean的实际文件混淆,并使其在rm出错的情况下继续运行。
(请参阅第29页的第4.5节[Phony目标]和第49页的第5.5节[Recipes中的错误]。)

A rule such as this should not be placed at the beginning of the makefile, because we do not want it to run by default!
Thus, in the example makefile, we want the rule for edit, which recompiles the editor, to remain the default goal.

诸如此类的规则不应放在 makefile 的开头,因为我们不希望它默认运行!
所以,在示例的 makefile 中,我们希望用于编译 edit 的规则保持不变。

Since clean is not a prerequisite of edit, this rule will not run at all if we give the command ‘make’ with no arguments.
In order to make the rule run, we have to type ‘make clean’. See Chapter 9 [How to Run make], page 99.

由于 clean 不是编译 edit 的先决条件(prerequisite ),因此,如果命令“ make”不带任何参数,则此规则将不会运行。
为了使规则生效,我们必须输入“ make clean”才行。 请参阅第9章[如何运行make],第99页。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章