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頁。

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