NAME
make - maintain program groups
SYNOPSIS
make [ -f makefile ] ... [ options ] ... name ...
DESCRIPTION
Make executes commands in makefile to update one or more
target
names. Name is typically a program. If no -f option is
present,
‘makefile’ and ‘Makefile’ are tried
in order. If makefile is ‘-’,
the standard input is taken. More than one -f option may
appear.
Make updates a target if it
depends on prerequisite files that have
been modified since the target was last modified, or if the
target
does not exist.
Makefile contains a sequence of
entries that specify dependencies.
The first line of an entry is a blank-separated list of
targets,
then a colon, then a list of prerequisite files. Text
following a
semicolon, and all following lines that begin with a tab,
are shell
commands to be executed to update the target. If a name
appears on
the left of more than one ‘colon’ line, then it
depends on all of
the names on the right of the colon on those lines, but only
one
command sequence may be specified for it. If a name appears
on a
line with a double colon :: then the command sequence
following
that line is performed only if the name is out of date with
respect
to the names to the right of the double colon, and is not
affected
by other double colon lines on which that name may
appear.
Dependencies can also appear in
a separate file ‘.depend’ which
Make will include automatically if no -f option is
present.
Two special forms of a name are
recognized. A name like a(b) means
the file named b stored in the archive named a. A name like
a((b))
means the file stored in archive a containing the entry
point b.
If the string
‘include’ appears as the first seven letters of
a
line in a makefile and is followed by blanks or tabs, the
following
string is assumed to be a file name which the current
invocation of
make will read. If the directive ‘-include’ is
used instead, it is
not fatal for the referenced file to be non-existent.
Sharp and newline surround comments.
The following makefile says that
‘pgm’ depends on two files ‘a.o’
and ‘b.o’, and that they in turn depend on
‘.c’ files and a common
file ‘incl’.
pgm: a.o b.o
cc a.o b.o -lm -o pgm
a.o: incl a.c
cc -c a.c
b.o: incl b.c
cc -c b.c
Makefile entries of the form
string1 = string2
are macro definitions.
Subsequent appearances of $(string1) or
${string1} are replaced by string2. If string1 is a single
character, the parentheses or braces are optional. #’s
in macro
definitions may be escaped with a backslash to avoid comment
stripping. Entries of the form
target := string1 = string2
are conditional macro
definitions: the definition is only made when
"target" is the current target name.
Make macros may be exported to
the environment by use of the
‘.EXPORT’ target. The following example shows
how to set and
export the PATH macro definition.
PATH=:/usr/local/bin:/usr/ucb:/bin:/usr/bin
.EXPORT: PATH
Make infers prerequisites for
files for which makefile gives no
construction commands. For example, a ‘.c’ file
may be inferred as
prerequisite for a ‘.o’ file and be compiled to
produce the ‘.o’
file. Thus the preceding example can be done more
briefly:
pgm: a.o b.o
cc a.o b.o -lm -o pgm
a.o b.o: incl
Prerequisites are inferred
according to selected suffixes listed as
the ‘prerequisites’ for the special name
‘.SUFFIXES’; multiple
lists accumulate; an empty list clears what came before.
Order is
significant; the first possible name for which both a file
and a
rule as described in the next paragraph exist is inferred.
The
default list is
.SUFFIXES: .out .o .s .c .f .e .r .y .l .p
The rule to create a file with
suffix s2 that depends on a
similarly named file with suffix s1 is specified as an entry
for
the ‘target’ s1s2. In such an entry, the special
macro $* stands
for the prefix shared by the current and the dependent file
names,
and $< for the name of the related file that caused the
action.
For example, a rule for making optimized ‘.o’
files from ‘.c’ files
is
.c.o: ; cc -c -O -o $@ $*.c
Before issuing any command the
special macro $@ is set to the full
target name, $> is set to the complete list of
prerequisites, and
$? to the list of prerequisites that are out of date.
Certain macros are used by the
default inference rules to
communicate optional arguments to any resulting
compilations. In
particular, ‘CFLAGS’ is used for cc(1) options,
‘FFLAGS’ for f77(1)
options, ‘PFLAGS’ for pc(1) options,
‘LFLAGS’ and ‘YFLAGS’ for lex
and yacc(1) options, and ‘LDFLAGS’ for ld(1)
options. In addition,
the macro ‘MFLAGS’ is filled in with the initial
command line
options supplied to make. This simplifies maintaining a
hierarchy
of makefiles as one may then invoke make on makefiles in
subdirectories and pass along useful options such as -k.
Another special macro is
‘VPATH’. The ‘VPATH’ macro should be
set
to a list of directories separated by colons. When make
searches
for a file as a result of a dependency relation, it will
first
search the current directory and then each of the
directories on
the ‘VPATH’ list. If the file is found, the
actual path to the
file will be used, rather than just the filename. If
‘VPATH’ is
not defined, or the file name begins with "./",
then only the
current directory is searched.
One use for ‘VPATH’
is when one has several programs that compile
from the same source. The source can be kept in one
directory and
each set of object files (along with a separate makefile)
would be
in a separate subdirectory. The ‘VPATH’ macro
would point to the
source directory in this case.
Command lines are executed one
at a time, each by its own shell. A
line is printed when it is executed unless the special
target
‘.SILENT’ is in makefile, or the first character
of the command is
‘@’.
Commands returning nonzero
status (see intro(1)) cause make to
terminate unless the special target ‘.IGNORE’ is
in makefile or the
command begins with <hyphen>.
Interrupt and quit cause the
target to be deleted unless the target
is a directory or is a dependent of the special name
‘.PRECIOUS’.
This version of make has been
upgraded to handle a number of
features found in the AT&T and SUN Microsystems
versions. The
following are brief descriptions (mostly taken from the SUN
Programming Tools document) of these features.
Translations in macro
references: There is a facility to perform
translations when a macro is referenced and evaluated. The
general
syntax of such a macro reference is:
$(macro_name:string_1=string_2)
This is interpreted as:
* The macro specified by
‘macro_name’ is evaluated,
* For each occurrence of ‘string_1’ in the
evaluated macro,
substitute ‘string_2’.
What constitutes an occurrence
of ‘string_1’ in the evaluated
macro? The evaluated macro is considered to be a set of
strings
each separated by whitespace (spaces or tabs). An occurrence
of
‘string_1’ in the evaluated macro means that a
regular expression
of this form has been found in the evaluated macro:
.*<string_1>[tab|space|eos]
A more general form of macro
translation is available using the
syntax
$(macro_name/regexp/replacement)
which will substitute
"replacement" for "regexp" in each
string
within the value of "macro_name". The regular
expression and
replacement string syntax are as described in regexp(3), and
’;’
characters may be used to delimit those elements instead of
’/’.
For example, given "LIST = a b c",
$(LIST/.*/x&y) would result in
the value "xay xby xcy". Note that the resulting
string is
evaluated for new macro references after substitution, so
$(LIST/.*/${&}) would result in the expanded values of
${a}, ${b},
and ${c}.
$(LIST:u) gives the unique
elements of $(LIST). That is, all
duplicates are removed.
Csh(1) style modifiers can also be applied. The general syntax is:
$(macro_name:modifier)
where ‘modifier’ is
one of ’h’, ’t’, ’r’,
’e’ (upper or lower
case), which produce respectively the head, tail, root, and
extension of the evaluated macro.
Recursive makefiles:
makefile’s can be set up so that they perform
recursive invocations of make. If the sequence $(MAKE)
appears
anywhere in a Shell command line, the line is executed even
if the
-n option was specified on the original make command line.
The -n
option is exported across invocations of make (via the
MAKEFLAGS
variable), so the only thing that gets executed is the make
command
itself. You can use this feature when a hierarchy of
makefile’s
describes a collection of subsystems. You can type
‘make -n’ and
everything that would happen is displayed without actually
executing the commands. Because of the $(MAKE) sequence, the
lower
level make’s get executed.
Extra macro forms: There are
some extra forms of macros, namely,
‘$(@D)’, ‘$(@F)’,
‘$(*D)’, ‘$(*F)’,
‘$(<D)’, and ‘$(<F)’. For each
of the macros, the ‘D’ refers to the Directory
part of the
corresponding ‘$@’, ‘$*’, or
‘$<’ macro, and the ‘F’ refers to
the
‘File’ part. These macros are used when building
hierarchical
makefile’s. For example, a Shell command could be:
cd $(@D) && $(MAKE) $(@F)
Dynamic dependency parameters:
The dynamic dependency parameter is
referenced by the ‘$$@’ notation. This dynamic
dependency
parameter only has meaning on the dependency line in a
makefile.
The ‘$$@’ refers to the current
‘thing’ to the left of the colon -
the ‘thing’ to the left of the colon is the
‘$@’ implicit macro
that would be defined during command execution. You can also
use
the form ‘$$(@F)’ which refers to the file part
of ‘$@’.
This dynamic dependency
parameter finds most use in maintaining a
bunch of programs that only depend on a single source file.
Suppose you have a directory with many small programs. You
could
have a makefile that looks something like this:
PROGRAMS = buzz biorhythm checkbook tictactoe
$(PROGRAMS): $$@.c
$(CC) $? -o $@
Assigning macros and variables:
make reads environment variables
and adds them to the macro definitions. make maintains a
macro
called ‘MAKEFLAGS’, which is a string defined as
the collection of
the current command line options (sans their minus sign).
The
‘MAKEFLAGS’ macro is exported and thus is
accessible to further
invocations of make. Here is how make assigns macro
definitions:
1. Read the MAKEFLAGS
environment variable. If MAKEFLAGS
does not exist or is null, set MAKEFLAGS to the null string.
Otherwise, each letter in MAKEFLAGS is taken to be a command
line option and is processed as such. The -f, -p, and -r
options do not get processed.
2. Read options from the command line. Options from the
command line add to the previous settings from the MAKEFLAGS
environment variable.
3. Read macro definitions from the command line. Such macro
definitions are made ‘non-resettable’ and any
further
assignments to these names are ignored.
4. Read make’s internal list of macro definitions.
5. Read the environment.
6. Read the makefile(s). Assignments in the makefile(s)
override the environment, unless you use the -e command line
option to tell make to have the environment override
assignments made in the makefile(s).
Making archive libraries: make
provides a mechanism for referring
to members of ‘ar’-style archive libraries. You
can name a member
of an object library as:
library_name(object_name.o)
or
library_name((_entry_point_name))
The first form refers to an
object name within a library. The
second form refers to an ‘entry point’ of an
object file within a
library. make searches the library to locate the entry point
and
then translates it to the correct object file name.
lib(obj1.o) lib(obj2.o) ... lib(objN.o)
can be abbreviated to
lib(obj1.o obj2.o ... objN.o)
Here is an example of a makefile
for building an archive from C
source:
LIB = libname.a
$(LIB): $(LIB)(obj1.o obj2.o ...
objN.o)
$(AR) r $(LIB) $?
$(RANLIB) $(LIB)
$(RM) $(RMFLAGS) $?
Note that this style of library
rule is subtly different from that
typically available. In particular, there is no magic
‘.a’ suffix
or associated macros - archive members will be built exactly
as if
they had been named directly.
Single suffix rules: If you have
many programs that are made from a
single source file it is tedious to maintain an object of
such
files. make supports single suffix rules. Suppose you have a
single program called ‘buzz’ that you maintain
from a single source
file ‘buzz.c’. You can maintain
‘buzz’ by a makefile entry that
looks like this:
.c:
$(CC) $(LDFLAGS) $(CFLAGS) $< -o $@
In fact, make defines the
‘.c’ rule internally so that no makefile
is even necessary. All you have to do is type
% make buzz
and make will do the correct thing.
%-style meta rules: Double and
single suffix style rules make many
assumptions about the way files are named and how they are
created.
A more general mechanism is available in which rules are
permitted
to contain variables. For example, a possible rule for
compiling C
programs is
%.o: %.c
$(CC) $(CFLAGS) -c %.c
where the % is the variable
symbol. This rule is actually a
template for creating rules, each of which is obtained by
consistently substituting a string for the variable %. There
are
11 variables: % and %0 to %9. A majority of rules in
practice have
only one variable (canonically called %), and most of the
other
rules have two (canonically called %1 and %2). Some more
examples
are:
%.c %.h: %.y
$(YACC) -d %.y
mv y.tab.h %.h
mv y.tab.c %.c
%1/%2:
cd %1 && $(MAKE) %2
The macro $% will also be set to
the value of the % variable. This
can be used in macro references within the dependency list
or
commands of a %-rule that would be unaffected by normal %
variable
substitution. If more than one %-rule can match a given
target,
then the rule that appears latest in the makefile will be
used.
Hence, more general rules should be listed first.
This version of make also
defines the macros ‘$(TARGET_MACHINE)’
and ‘$(target_machine)’, the latter being a
lower case version of
the former value. The supported machine types currently
include:
PDP11, VAX, SUN2, SUN3, SUN4,
IBMRT, BALANCE, MMAX, PMAX,
I386, MACII.
The macros $(CPUTYPE) and
$(cputype) define the specific
architecture of the machine type. For example, on a SUN3,
$(CPUTYPE) is MC68020. On both the BALANCE and MMAX,
$(CPUTYPE) is
NS32032.
The -m flag causes make to
search the sub-directory
$(TARGET_MACHINE) before the current directory and any
‘VPATH’
components when looking for a file. This means that machine
specific versions of files can automatically be used instead
of
machine independent ones.
A rudimentary form of
conditional expression is available by using
a macro reference ‘inside’ a macro name. For
example, given the
following definitions,
VAXFLAGS = foo
MMAXFLAGS = bar
...
the sequence
$(${TARGET_MACHINE}FLAGS) would be replaced by the
string for the current machine type.
Another style of conditional
expression is available with the macro
form $(NAME?string1:string2), which yields
"string1" if $(NAME) is
defined, and "string2" otherwise.
Directly recursive macro definitions: Macro definitions of the form
NAME = string1$(NAME)string2
are now legal. The occurrence of
$(NAME) in the right-hand side
will be expanded at definition time. This can be used to
easily
add new components to macros like CFLAGS or PATH. For
example,
CFLAGS = -O $(CFLAGS)
PATH = /somedir:$(PATH):/anotherdir
Separating OBJECT and SOURCE
directories: The ability to compile
multiple versions of a system from common source is an
important
feature, particularly with the advent of shared file systems
where
different object formats must co-exist. This version of make
provides a mechanism for easily specifying separate object
directories.
When make is invoked, it
searches for a configuration file,
‘Makeconf’, in the current directory, the parent
directory, and
every directory back to the root. If a configuration file is
found, it is read as a normal makefile. If the macro
‘OBJECTDIR’
is defined within the configuration file its value will be
interpreted as the object tree root. That is, the name of
the
object directory is created by appending the difference
between the
directory where ‘Makeconf’ was found and the
original directory to
the end of $(OBJECTDIR). Make will then chdir to the object
directory, creating subdirectories of $(OBJECTDIR) if
necessary,
and modify ‘VPATH’ so that source files will be
found in the
original directory. Processing will then proceed as normal,
with
all files being created in the object directory. The
‘OBJECTDIR’
definition will typically be a function of both the current
machine
type and a system version name. For example,
OBJECTDIR = @$(TARGET_MACHINE).$(VERSION)
The placement of the
‘Makeconf’ file determines the granularity of
object trees. For example, a single ‘Makeconf’
in /usr/src would
mean a single object tree in parallel to the source.
Alternatively, there could be a separate
‘Makeconf’ and object tree
for each sub-system. Recursive make’s and manual
make’s from sub-
directories will all do the "right-thing". If the
macro
‘SOURCEDIR’ is defined within the configuration
file, its value
will be interpreted as a :-separated list of alternate
source tree
roots, and ‘VPATH’ will be modified accordingly.
The macros
‘MAKEDIR,’ ‘MAKETOP,’ and
‘MAKESUB’ are set to values useful in
constructing pathnames in installation lines, or for
referring to
other files in the source tree. The ‘Makeconf’
file may also
contain other version independent macro definitions and
rules,
although such usage is discouraged.
The special target .INOBJECTDIR
can be used to specify that certain
files should have versions "made" in the object
directory. That
is, it is a means to specify dependencies that conceptually
look
like "$(OBJECTDIR)/file: $(SOURCEDIR)/file" for
some value of
"file". The dependencies of the .INOBJECTDIR
target are the
files that will be considered for such treatment, and the
rules
give the commands for creating the OBJECTDIR version. For
example,
.INOBJECTDIR: file1 file2 ...
cp -p $< ./$<
Note the use of "./"
to avoid having the second occurrence of $<
rewritten to reference the source directory.
The special targets .INIT and
.EXIT will be made before and after,
respectively, the normal targets.
Make now also understands about
RCS files. If a file is required
and doesn’t exist, then the current directory and all
‘VPATH’
components, both with and without a trailing
‘/RCS’, are searched
for the filename with extension ‘,v’. If such a
file is found, it
is automatically ‘checked-out’, used, and then
removed. The -c
flag suppresses the automatic check-out, while the -u flag
suppresses the removal.
By default, the update time of a
‘,v’ file is taken from its time
of last modification. However, by specifying a rule for the
special target ‘.RCSTIME’, the "real"
modification time of a
particular revision may be determined. ‘$<’
will be set to the
name of the ‘,v’ file before invoking the
command, which is
expected to print the time (in decimal ‘time_t’
format) on the
standard output. Under Mach the ‘rcstime’
command has been
provided for this purpose, so an appropriate
‘.RCSTIME’ definition
would be:
.RCSTIME:
@rcstime $(COFLAGS) $<
Other options:
-c If a file does not exist, do
not try to find a corresponding
RCS file and check it out.
-C Try to get the file from RCS
(this is the default). The
command used is: ‘$(CO) $(COFLAGS) $< $@’
where CO=co and
COFLAGS=-q by default.
-d Print debugging information
(relatively useless except for
trying to find out what went wrong).
-e Environment variables override assignments within makefiles.
-i Equivalent to the special entry ‘.IGNORE:’.
-k When a command returns
nonzero status, abandon work on the
current entry, but continue on branches that do not depend
on
the current entry.
-S The inverse of -k (default).
-n Trace and print, but do not
execute the commands needed to
update the targets.
-p Print a version of the input graph.
-q Don’t do anything, but
check if object is up to date. Return
exit status 0 if it is, non-zero if it is not.
-r Do not use the implicit rules make supplies by default.
-s Equivalent to the special entry ‘.SILENT:’.
-t Touch, i.e. update the
modified date of targets, without
executing any commands.
-m Search machine specific subdirectories automatically.
-F The absence of a description file becomes a fatal error.
-N Disable all "Makeconf" processing.
-x Don’t execute any
commands except for check-outs, and don’t
unlink checked-out files. Useful for creating working
versions of the sources for the given target.
-y Check "foo: [RCS/]foo,v
dependencies. Useful for ensuring
that the working versions of sources are indeed the latest
revision.
-u Don’t unlink files that
were automatically checked-out from
RCS.
-U Unlink files that were
automatically checked-out from RCS,
unless they are listed in the ".PRECIOUS" target
(default).
-b This option has no effect,
but is present for compatibility
reasons.
ENVIRONMENT
Make exports the following environment variables for use by
sub-
makes: MAKEFLAGS, MAKECONF, MAKECWD, MAKEPSD. Also exported
are
MAKECPP and MAKEMCH, which contain a colon separated list of
the
directories considered to be equivalent under VPATH
searching, and
the name of the machine-specific subdirectory (see -m
option)
respectively. These are useful for other programs, like cpp,
that
do some form of file searching.
FILES
makefile, Makefile, Makeconf
SEE ALSO
sh(1), touch(1), cc(1), f77(1), pc(1), co(1)
S. I. Feldman Make - A Program for Maintaining Computer
Programs
(included in the MachTen Programmer’s Guide)
BUGS
Some commands return nonzero status inappropriately. Use -i
to
overcome the difficulty. Commands that are directly executed
by
the shell, notably cd(1), are ineffectual across newlines in
make.
‘VPATH’ is intended
to act like the System V ‘VPATH’ support, but
there is no guarantee that it functions identically.