[Next] [Previous] [Up] [Top] [Contents] [Index]
Chapter 17: The make Utility
The Makefile is a blueprint that you design and make uses to create or update one or more target files based on the most recent modify dates of the required files. The make command line syntax remains quite simple in the case where a Makefile is used:
% make [-f makefile_name] [other options] [targets]
If the -f option is not used, make checks for a Makefile of a particular name: it first looks in the current directory for a file named makefile, then for Makefile. If the Makefile is still not found, make looks in a couple of other places (see the man pages). In order to keep things simple and standard, we recommend that you always use the filename Makefile for your Makefile(s). Following this convention, you'll have only one Makefile in a directory. Your Makefile can contain instructions for building many different targets. When executing make, you can specify the desired target(s) on the make command line.
We can categorize the types of statements that can go in a Makefile as follows:
A macro is a name that you define to represent a variable that may occur several times within the Makefile.
A target definition lists the target file, its required files, and the commands to execute on the required files in order to produce the target. (You can opt to specify the totality of this information in separate target definitions.)
Suffix rules indicate the relationship between target and source file suffixes (filename extensions). For example in FORTRAN, object files (*.o) are created from source files with a suffix of f (i.e. *.f). If no source file is explicitly given on a target definition line, make uses suffix rules to determine what source file to use to produce the target.
Suffix declarations are lists of suffixes (file extensions) used in suffix rules.
Each new line in the Makefile starts a new definition, except that in target definitions:
\)
Blank lines are permitted between definitions. Comments can be included after a pound sign (#). To use a literal pound sign, precede it with a backslash, i.e. \#.
A macro is a name that you define to represent a variable that may occur several times within the Makefile, or that needs to be updated frequently. Macros make maintenance of your Makefile much easier. They are commonly used to define settings, platform-specific commands, lists of required files for a target, lists of command options, and so on. make reads all the macro definitions before executing any commands. It is often convenient to put all the macro definitions at the head of the Makefile, but this is not necessary.
Macro definitions are of the form:
macro_name = value
where macro_name is the name you want to use in place of the longer value. Everywhere in the Makefile that macro_name is found, make substitutes value. For portability, if value contains any blank spaces that it is supposed to have, the value string must be enclosed in quotes in the definition statement.[81] Backslashes can be used to continue the same line; you cannot put a new line in a macro value.
Once a macro is defined, you refer to its value in the form $(macro_name). If macro_name is a single character, you can omit the parentheses.
As an example, let's define a macro FFLAGS to set some FORTRAN default options to use with the f77 command:
FFLAGS = "-O2 -w -Olimit 1500 -nocpp "
You can now refer to the value of FFLAGS within the Makefile in the form $(FFLAGS). For example, you might include a target definition line like the following (the format is explained below in section 17.2.2):
foo : foo.f ; f77 -o foo $(FFLAGS) foo.f
[Missing image]To be sure that make uses the standard, portable Bourne shell, always include in your Makefile a macro of the form:
SHELL = /bin/sh
Some versions of make default to your current interactive shell if you don't include this explicit SHELL macro in your Makefile. The standard Makefile format that we describe in this chapter assumes sh as the command interpreter.
Macro definitions are similar to and can take default values from environment variables. make gets additional macro definitions from the following sources, and applies them in the order shown:
In other words, this list is in order of reverse precedence; a value from a source later in the list overrides a value applied from an earlier one. Using the -e option on the make command line swaps the first two; see section 17.3.1.
$$ maps to a literal dollar sign
$* is used in suffix rules (see section 17.2.3); it refers to the filename without the suffix
$@ is the current target make is processing
$< is the implied source in a suffix rule
Targets are the files that you want to update or create. A complete target definition includes the name of the target, the files needed to build it (its required files), and the commands that must be executed to recreate the target.
The standard Makefile format using Bourne shell conventions calls for:
:) between the last target and the first required file
;) after the last required file if commands follow on the same line
;) between the successive listed commands
A simple target definition with a single target, required file, and command can be written in the form:
target : required_file ; shell_command
or, using a more traditional format, listing the command on the next line (note that the semicolon (;) is omitted here):
target: required_file{tab}shell_command
In this traditional Makefile format, the commands beyond the first line of a definition must have leading tabs, and there must be no intervening blank lines.
There are two reasons to avoid this second format: first, when working with the Makefile it is hard to see the difference between a tab and blanks, and secondly, some editors change tabs to blanks (or vice versa), which causes problems (neither emacs in default mode nor vi changes tabs to blanks). You can check your file to see if it contains tabs or blanks by running the command:
cat -tev filename
We propose as an alternative that you use the backslash character (\) to continue the single definition line down as many physical lines as you have to go. Also, note that under AIX the standard "tabbed" format can be unpredictable; it is therefore safer for several reasons to use our suggested format on this platform.
This "safer" format which we suggest if the entire definition doesn't fit on the first line is:
target : required_file; \
shell_command
A target definition line can contain more than one of each element type. Or, it may contain only two of the three element types. A more complex definition in our suggested format looks like:
target_1 target_2 ... : required_file_1 required_file_2 ... required_file_n \ required_file_n+1 ...; \ shell_command_1 ; shell_command_2 ; shell_command_3 ; ... ; \ . . . ... ; shell_command_m |
If there is more than one target (e.g. target_1 target_2) in one definition, the commands are attempted separately for each target.
If you find it easier, you can list multiple required files for a single target in separate target statements. However only one statement for a given target can include commands, and therefore must include all the commands. Here is an example of this alternative format:
target : required_file_1 target : required_file_2 target : required_file_3 target : ; shell_command_1 ; shell_command_2 ; shell_command_3 ; ... |
[Missing image]It can be confusing if you separate a series of statements like this from one another in the Makefile; if you use this format, keep the statements together!
The relative modification times of the target and the required_file(s) determine whether the listed commands will be executed. If the target file is found to be missing or to be older than any of its required files, make executes the commands to rebuild it. make treats the required files iteratively as targets, whether or not they are explicitly listed as targets in subsequent target definitions, and rebuilds them as necessary before rebuilding the final target.
A suffix is essentially a file extension. A suffix rule defines the relationship between target and required files by their file extensions. A suffix rule is much like a target definition except that it uses implied rather than explicit file names for target (output) and required (input) files.
A suffix rule is of the form:
.insuffix.outsuffix : ; command
The dots are really part of the suffixes themselves. As an example, assume you have a set of target files to rebuild whose filenames are all of the form *.b. The required files for these targets have filenames of the form *.a. Define the suffix rule:
.a.b : ; command(s)
make expands this to the following target definition for all files ending in .a in the current directory:
filename.b : filename.a ; command(s)
If you define suffix rules specifically for intermediate files in a process, you still need to include a rule for the final and original files, for example, if you define:
.tex.dvi: ; latex $* #latex cmd makes .dvi files from .tex files
.dvi.ps: ; dvips $* #dvips cmd makes .ps files from .dvi files
You still need to provide the rule:
.tex.ps: ; latex $*; dvips $* #make .ps files from .tex files
make is not sophisticated enough to do the transitive closure on suffix rules.
Note that suffixes don't have to start with a dot (.).
Any suffix that you use in a suffix rule must be listed explicitly in a .SUFFIXES declaration in the same Makefile unless it is included in make's built-in suffix declarations (see section 17.6). A suffix included in the built-ins can also be included in a suffix declaration in the Makefile.
Suffix declarations are really target definitions for a special target named .SUFFIXES and they contain no commands.[82] They are of the format:
.SUFFIXES : .a .b
where .a and .b are suffixes. This example suffix declaration would allow you to include the suffix rule from 17.2.3 in your Makefile:
.a.b : ; command(s)
You may combine all the suffixes you use in the Makefile into one .SUFFIXES declaration, or group them into separate statements.
Suffixes that you declare add to the built-ins; they do not replace them.
You may encounter situations where it is useful to pipe input or output of one command to another within a Makefile. You can echo a small control or data file within the Makefile, rather than maintaining a separate external file. In the following target definition example from an Isajet Makefile, several control statements are echoed into the patchy utility in order to extract isaint.f from the isajet.car patchy library:
isaint.f : isajet.car ; \
(echo "+USE,*ISAJET,$(MACHINE). "; \
echo "+USE,INTERACT. INTERACTIVE PATCH "; \
echo "+EXE. "; \
echo "+PAM,T=C. "; \
echo "+QUIT. ";)\
| ypatchy isajet.car isaint.f \& genint.lis .GO
$(FFLAGS) to a program to execute. If you want leading or trailing spaces in value to be included in the command, specify the macro in double quotes in the command statement, e.g., "$(FFLAGS)".
.SUFFIXES. These special target names always start with a dot (.).