第二章

来源:互联网 发布:iatf16949过程矩阵图 编辑:程序博客网 时间:2024/04/29 23:56

 

2 An Introduction to Makefles
 
 
You need a fle called a makefle to tell make what to do. Most often, the makefle tells make
how to compile and link a program.
In this chapter, we will discuss a simple makefle that describes how to compile and link
a text editor which consists of eight C source fles and three header fles. The makefle can
also tell make how to run miscellaneous commands when explicitly asked (for example, to
remove certain fles as a clean-up operation). To see a more complex example of a makefle,
see Appendix C [Complex Makefle], page 153.
When make recompiles the editor, each changed C source fle must be recompiled. If a
header fle has changed, each C source fle that includes the header fle must be recompiled to
be safe. Each compilation produces an object fle corresponding to the source fle. Finally,
if any source fle has been recompiled, all the object fles, whether newly made or saved
from previous compilations, must be linked together to produce the new executable editor.

 

2.1 What a Rule Looks Like
A simple makefle consists of “rules” with the following shape:
target ... : prerequisites ...
command
...
...
A target is usually the name of a fle that is generated by a program; examples of targets
are executable or object fles. A target can also be the name of an action to carry out, such
as ‘clean’ (see Section 4.5 [Phony Targets], page 30).
A prerequisite is a fle that is used as input to create the target. A target often depends
on several fles.
A command is an action that make carries out. A rule may have more than one command,
each on its own line. Please note: you need to put a tab character at the beginning of every
command line! This is an obscurity that catches the unwary.
Usually a command is in a rule with prerequisites and serves to create a target fle if any
of the prerequisites change. However, the rule that specifes commands for the target need
not have prerequisites. For example, the rule containing the delete command associated
with the target ‘clean’ does not have prerequisites.
A rule, then, explains how and when to remake certain fles which are the targets of the
particular rule. make carries out the commands 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 23.
A makefle may contain other text besides rules, but a simple makefle need only contain
rules. Rules may look somewhat more complicated than shown in this template, but all ft
the pattern more or less.
 
 

4

 

2.2 A Simple Makefle
 

GNU make
 
Here is a straightforward makefle that describes the way an executable fle called edit
depends on eight object fles which, in turn, depend on eight C source and three header
fles.
In this example, all the C fles include ‘defs.h’, but only those defning editing commands
include ‘command.h’, and only low level fles that change the editor bufer include ‘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.
To use this makefle to create the executable fle called ‘edit’, type:
make
To use this makefle to delete the executable fle and all the object fles from the directory,
type:
make clean
In the example makefle, the targets include the executable fle ‘edit’, and the object
fles ‘main.o’ and ‘kbd.o’. The prerequisites are fles such as ‘main.c’ and ‘defs.h’. In
fact, each ‘.o’ fle is both a target and a prerequisite. Commands include ‘cc -c main.c’
and ‘cc -c kbd.c’.
When a target is a fle, 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 frst. In this example, ‘edit’ depends on each of the eight object fles; the object
fle ‘main.o’ depends on the source fle ‘main.c’ and on the header fle ‘defs.h’.
 
 

Chapter 2: An Introduction to Makefles
 

5
 

 

A shell command follows each line that contains a target and prerequisites. These shell
commands say how to update the target fle. A tab character must come at the beginning
of every command line to distinguish command lines from other lines in the makefle. (Bear
in mind that make does not know anything about how the commands work. It is up to you
to supply commands that will update the target fle properly. All make does is execute the
commands in the rule you have specifed when the target fle needs to be updated.)
The target ‘clean’ is not a fle, 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 specifcally. 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 specifed commands. Targets that do not refer to fles
but are just actions are called phony targets. See Section 4.5 [Phony Targets], page 30, for
information about this kind of target. See Section 5.5 [Errors in Commands], page 48, to
see how to cause make to ignore errors from rm or any other command.

2.3 How make Processes a Makefle
By default, make starts with the frst target (not targets whose names start with ‘.’). This
is called the default goal. (Goals are the targets that make strives ultimately to update. You
can override this behavior using the command line (see Section 9.2 [Arguments to Specify
the Goals], page 91) or with the .DEFAULT_GOAL special variable (see Section 3.6 [Other
Special Variables], page 14).
In the simple example of the previous section, the default goal is to update the executable
program ‘edit’; therefore, we put that rule frst.
Thus, when you give the command:
make
make reads the makefle in the current directory and begins by processing the frst 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 fles that ‘edit’ depends on, which in this case are the object
fles. Each of these fles is processed according to its own rule. These rules say to update
each ‘.o’ fle by compiling its source fle. The recompilation must be done if the source fle,
or any of the header fles named as prerequisites, is more recent than the object fle, or if
the object fle does not exist.
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).
Before recompiling an object fle, make considers updating its prerequisites, the source
fle and header fles. This makefle does not specify anything to be done for them—the ‘.c’
and ‘.h’ fles are not the targets of any rules—so make does nothing for these fles. But
make would update automatically generated C programs, such as those made by Bison or
Yacc, by their own rules at this time.
After recompiling whichever object fles need it, make decides whether to relink ‘edit’.
This must be done if the fle ‘edit’ does not exist, or if any of the object fles are newer than
it. If an object fle was just recompiled, it is now newer than ‘edit’, so ‘edit’ is relinked.
 
 

6
 

GNU make

 

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

2.4 Variables Make Makefles Simpler
In our example, we had to list all the object fles twice in the rule for ‘edit’ (repeated here):
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 fle is added to the system, we might
add it to one list and forget the other. We can eliminate the risk and simplify the makefle
by using a variable. Variables allow a text string to be defned once and substituted in
multiple places later (see Chapter 6 [How to Use Variables], page 57).
It is standard practice for every makefle to have a variable named objects, OBJECTS,
objs, OBJS, obj, or OBJ which is a list of all object fle names. We would defne such a
variable objects with a line like this in the makefle:
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 fle names, we can substitute the
variable’s value by writing ‘$(objects)’ (see Chapter 6 [How to Use Variables], page 57).
Here is how the complete simple makefle looks when you use a variable for the object
fles:
 
 

Chapter 2: An Introduction to Makefles

 

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 Commands
 

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

 


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

 


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

8
 

 

 


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)
 

GNU make
 

This is how we would write the makefle in actual practice. (The complications associ-
ated with ‘clean’ are described elsewhere. See Section 4.5 [Phony Targets], page 30, and
Section 5.5 [Errors in Commands], page 48.)

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


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

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 fles; ‘command.h’ and ‘buffer.h’
are prerequisites of the specifc object fles listed for them.

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

Chapter 2: An Introduction to Makefles

 

2.7 Rules for Cleaning the Directory
 

9
 
Compiling a program is not the only thing you might want to write rules for. Makefles
commonly tell how to do a few other things besides compiling a program: for example, how
to delete all the object fles and executables so that the directory is ‘clean’.
Here is how we could write a make rule for cleaning our example 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 fle called ‘clean’ and causes it
to continue in spite of errors from rm. (See Section 4.5 [Phony Targets], page 30, and
Section 5.5 [Errors in Commands], page 48.)
A rule such as this should not be placed at the beginning of the makefle, because we do
not want it to run by default! Thus, in the example makefle, we want the rule for edit,
which recompiles the editor, to remain the default goal.
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 91.
 

原创粉丝点击