Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ make(CP) — OpenDesktop Software Development System 3.0.0

Media Vault

Software Library

Restoration Projects

Artifacts Sought

Related Articles

cc(CP)

cd(C)

lex(CP)

printf(S)

sccsfile(FP)

sh(C)

yacc(CP)


 make(CP)                       6 January 1993                       make(CP)


 Name

    make - maintain, update, and regenerate groups of programs

 Syntax

    make [-f makefile] [-piksrnbBetqd] [names] [macro definitions]

 Description

    make allows the programmer to maintain, update, and regenerate groups of
    computer programs.  The following is a brief description of all options
    and some special names:

    -f makefile  Description file name.  makefile is assumed to be the name
                 of a description file.

    -p           Print out the complete set of macro definitions and target
                 descriptions.

    -i           Ignore error codes returned by invoked commands.  This mode
                 is entered if the fake target name .IGNORE appears in the
                 description file.

    -k           Abandon work on the current entry if it fails, but continue
                 on other branches that do not depend on that entry.

    -s           Silent mode.  Do not print command lines before executing.
                 This mode is also entered if the fake target name .SILENT
                 appears in the description file.

    -r           Do not use the built-in rules.

    -n           No execute mode.  Print commands, but do not execute them.
                 Even lines beginning with an @ are printed.

    -b           Compatibility mode for old makefiles; this is the default
                 mode.

    -B           Turn off compatibility mode for old makefiles.

    -e           Environment variables override assignments within makefiles.

    -t           Touch the target files (causing them to be up-to-date)
                 rather than issue the usual commands.

    -q           Question.  The make command returns a zero or non-zero
                 status code depending on whether the target file is or is
                 not up-to-date.

    Special targets


    .DEFAULT     If a file must be made but there are no explicit commands or
                 relevant built-in rules, the commands associated with the
                 name .DEFAULT are used if it exists.

    .PRECIOUS    Dependents of this target will not be removed when quit or
                 interrupt are hit.

    .SILENT      Same effect as the -s option.

    .IGNORE      Same effect as the -i option.

    make evaluates the dependencies specified in makefile and executes the
    associated commands to update one or more targets, specified by name.
    Targets typically are programs.  If no -f option is present, then the
    files makefile, Makefile, and the Source Code Control System (SCCS) files
    s.makefile, and s.Makefile are tried in order.  If makefile is -, the
    standard input is read.  More than one -f makefile argument pair may
    appear.

    make updates a target only if its dependents are newer than the target.
    All prerequisite files of a target are added recursively to the list of
    targets.  Missing files are deemed to be out-of-date, that is, they are
    newer than the target.

    makefile contains a sequence of entries that specify dependencies. A
    dependency has the following syntax:

       target1 [target2 ... ] :[:] [dependency1 ... ] [; commands [# ... ]
       [[<Tab> commands][# ... ]
       ...
       ]


    (<Tab> is the tab character on your keyboard. It is printed here as
    <Tab>, instead of a sequence a blank characters for the purposes of this
    description.)

    Tokens on the first line of an entry are blank-separated. The first non-
    empty line that does not begin with a tab or # begins a new dependency or
    macro definition. If the targets are separated from the dependent files
    by double colon (::), then the targets can appear in several dependen-
    cies. Each such dependency will be evaluated separately, using the origi-
    nal last modification time of the target to determine whether the com-
    mands are executed.

    Shell commands and comments may be continued across lines with the
    <backslash><new-line> sequence. Everything printed by make (except the
    initial tab) is passed directly to the shell as is. If the last character
    on a line is a backslash, then the backslash and the new-line character
    are replaced by a single blank.

    Sharp (#) and new-line surround comments.  The following makefile says
    that pgm depends on two files a.o and b.o, and that they in turn depend
    on their corresponding source files (a.c and b.c) and a common file
    incl.h:

       pgm: a.o b.o
          cc a.o b.o -o pgm

       a.o: incl.h a.c
          cc -c a.c

       b.o: incl.h b.c
          cc -c b.c

    Command lines are executed one at a time, each by its own shell.  The
    SHELL environment variable can be used to specify which shell make should
    use to execute commands.  The default is the users default shell.  The
    first one or two characters in a command can be the following: -, @, -@,
    or @-.  If @ is present, printing of the command is suppressed.  If - is
    present, make ignores return codes.  A line is printed when it is exe-
    cuted unless the -s option is present, or the entry .SILENT: is in
    makefile, or unless the initial character sequence contains a @.  The -n
    option specifies printing without execution; however, if the command line
    has the string $(MAKE) in it, the line is always executed (see discussion
    of theMAKEFLAGS macro under ``Environment'').  The -t (touch) option
    updates the modified date of a file without executing any commands.

    Commands returning non-zero status normally terminate make.  If the -i
    option is present, or the entry .IGNORE: appears in makefile, or the ini-
    tial character sequence of the command contains -, the error is ignored.
    If the -k option is present, work is abandoned on the current entry, but
    continues on other branches that do not depend on that entry.

    Interrupt and quit cause the target to be deleted unless the target is a
    dependent of the special name .PRECIOUS.

    Environment

    The environment is read by make.  All variables are assumed to be macro
    definitions and processed as such.  The environment variables are pro-
    cessed before any makefile and after the internal rules; thus, macro
    assignments in a makefile override environment variables.  The -e option
    causes the environment to override the macro assignments in a makefile.
    Suffixes and their associated rules in the makefile will override any
    identical suffixes in the built-in rules.

    The MAKEFLAGS environment variable is processed by make as containing any
    legal input option (except -f and -p) defined for the command line.
    Further, upon invocation, make ``invents'' the variable if it is not in
    the environment, puts the current options into it, and passes it on to
    invocations of commands.  Thus, MAKEFLAGS always contains the current
    input options.  This proves very useful for ``super-makes''.  In fact, as
    noted above, when the -n option is used, the command $(MAKE) is executed
    anyway; hence, one can perform a make -n recursively on a whole software
    system to see what would have been executed.  This is because the -n is
    put in MAKEFLAGS and passed to further invocations of $(MAKE).  This is
    one way of debugging all of the makefiles for a software project without
    executing the commands in the makefile.

    If a macro named VPATH is assigned a list of colon separated directory
    names, make will search these directories when looking for files with
    relative path names, in the same way the shells use the PATH environment
    variable.

    Include files

    If the string include appears as the first seven letters of a line in a
    makefile, and is followed by a blank or a tab, the rest of the line is
    assumed to be a filename and will be read by the current invocation,
    after substituting for any macros.

    Inference rules

    make has a set of internal rules for building files which control the
    inference of prerequisites.  Any target that has no slashes in it and
    starts with a dot is identified as a rule and not a true target.  For
    example, the rule to create a file with suffix .o from a file with suffix
    .c is specified as an entry with .c.o: as the target and no dependents.
    Shell commands associated with the target define the rule for making a .o
    file from a .c file.  You may add rules to this list by simply putting
    them in the makefile.

    Using the inference rules, the first example can be done more briefly.

       pgm: a.o b.o
       cc a.o b.o -o pgm
       a.o b.o: incl.h


    Certain macros are used by the default inference rules to permit the
    inclusion of optional matter in any resulting commands.  For example,
    CFLAGS, LFLAGS, and YFLAGS are used for compiler options to cc(CP),
    lex(CP), and yacc(CP), respectively.  Use the -p option to list the
    internal rules.


    Macros

    Entries of the form string1 = string2 and string3 == string4 are macro
    definitions. Subsequent appearences of $(string1[:subst1=subst2]) on
    dependency lines or in shell commands are replaced by string2. Subsequent
    appearences of $(string3[:subst1=subst2]) anywhere in the description
    file are replaced by string4.  Strings (for the purposes of this type of
    substitution) are delimited by blanks, tabs, newline characters, and
    beginnings of lines.

    The optional :subst1=subst2 is a substitute sequence. The parentheses are
    optional if a single character macro name is used and there is no substi-
    tute sequence. If a substitute sequence is specified, all nonoverlapping
    occurances of subst1 in the named macro are replaced by subst2.

    If string2 in the single equal sign assignment contains macros, they are
    not evaluated until string1 is evaluated in a dependency line or a com-
    mand line. This saves time and space. However, if two or more substitu-
    tion operator assignments are done using single equal sign assignments,
    an error will occur when the macro is evaluated on a dependency line or
    command line because make does not support nested evaluations of the sub-
    stitution operator. For example, if the description file is

       SRC=src/file1.c src/file2.c src/file3.c
       TMP=$(SRC:.c=.o)
       OBJ=$(TMP:src=obj)

       all: $(SRC)

       clean:
               rm $(OBJ)


    and you execute it, requesting clean to be updated, an error will occur
    because make will only evaluate the outer substitution operator of $(OBJ)
    resulting in the shell executing rm $(SRC:src=obj). If the double equal
    sign assignment were used in the TMP assignment, then TMP would immedi-
    ately be evaluated, removing the inner substition operator from OBJ and
    the clean target would evaluate correctly.

    Internal macros

    There are five internally maintained macros that are useful for writing
    rules for building targets.

    $*   $* stands for the filename part of the current dependent with the
         suffix deleted.  It is evaluated only for inference rules.

    $@   $@ stands for the full target name of the current target.  It is
         evaluated only for explicitly named dependencies.

    $<   $< is only evaluated for inference rules or the .DEFAULT rule.  It
         is the module that is out-of-date with respect to the target (that
         is, the ``manufactured'' dependent file name).  Thus, in the .c.o
         rule, the $< macro would evaluate to the .c file.  An example for
         making optimized .o files from .c files is:

       .c.o:
            cc -c -O $*.c

       or:

       .c.o:
            cc -c -O $<

    $?   $? is evaluated when explicit rules from the makefile are evaluated.
         It is the list of prerequisites that are out-of-date with respect to
         the target; essentially, those modules which must be rebuilt.

    $%   $% is only evaluated when the target is an archive library member of
         the form lib(file.o).  In this case, $@ evaluates to lib and $%
         evaluates to the library member, file.o.

    $!   $! evaluates to target name, if the target is the default target or
         if it was requested on the command line, or to the list of targets
         which were called as the result of dependency relationships.  For
         example, suppose the description file is:

            p q: r
                    @echo $!
            r: s
                    @echo $!
            s:
                    @echo $!


         If this file were called requesting 'q' be updated, then the follow-
         ing would be printed:

            s r q
            r q
            q

         The line s r q is printed by echo following the s target, the line r
         q is printed by echo following the r target, and the line q is
         printed by echo following the p q targets.

    All of the internal macros can have an alternative form.  When an upper-
    case D or F is appended to any of the macros, the meaning is changed to
    ``directory part'' for D and ``file part'' for F.  Thus, $(@D) refers to
    the directory part of the string $@.  If there is no directory part, ./
    is generated.

    Suffixes

    The make program uses an internal table of rules to learn how to
    transform a file with one suffix into a file with another. Certain names
    (for example, those ending with .o) have inferrible prerequisites such as
    .c, .s, etc.  These transformation rules names are the concatenation of
    two suffixes. For example the name of the rule to transform a .r file to
    a  .o is .r.o.  If a target is whose suffix corresponds to one of the
    internal rules is listed in a makefile and no explicit commands are given
    in its dependency, or if a file is a dependent of another target and no
    target is explicitly given for it but its suffix matches one of the
    internal rule suffixes, then the commands for the corresponding internal
    rule are used to make the target.

    To print out the rules compiled into make on any machine in a form suit-
    able for reuse, the following command is used:

       make -fp - 2>/dev/null </dev/null

    A tilde in the above rules refers to an SCCS file (see sccsfile(FP)).
    Thus, the rule .c~.o would transform an SCCS C source file into an object
    file (.o).  Because the s. of the SCCS files is a prefix, it is incompa-
    tible with make's suffix point of view.  Hence, the tilde is a way of
    changing any file reference into an SCCS file reference.

    A rule with only one suffix (for example, .c:) is the definition of how
    to build x from x.c.  In effect, the other suffix is null.  This is use-
    ful for building targets from only one source file (for example, shell
    procedures, simple C programs).

    Additional suffixes can be given as the dependency list for .SUFFIXES.
    Order is significant; the first possible name for which both a file and a
    rule exist is inferred as a prerequisite.  The default list is:

       .SUFFIXES: .o .c .c~ .y .y~ .l .l~ .s .s~ .sh .sh~ .h .h~ .f .f~ .asm
       .asm~ .src .src~ .inc .inc~

    Here again, the above command for printing the internal rules will dis-
    play the list of suffixes implemented on the current machine.  Multiple
    suffix lists accumulate; .SUFFIXES: with no dependencies clears the list
    of suffixes.

    Libraries

    If a target or dependency name contains parentheses, it is assumed to be
    an archive library, the string within parentheses referring to a member
    within the library.  Thus lib(file.o) and $(LIB)file(.o) both refer to an
    archive library that contains file.o.  (This assumes the LIB macro has
    been previously defined.) The expression $(LIB)(file1.o file2.o) is not
    legal.  Rules pertaining to archive libraries have the form .XX.a where
    the XX is the suffix from which the archive member is to be made.
    An unfortunate byproduct of the current implementation requires the XX to
    be different from the suffix of the archive member.  Thus, one cannot
    have lib(file.o) depend upon file.o explicitly.  The most common use of
    the archive interface follows.  Here, we assume the source files are all
    C type source:

       lib: lib(file1.o) lib(file2.o) lib(file3.o)
               @echo lib is now up-to-date
       .c.a:
               $(CC) -c $(CFLAGS) $<
               $(AR) $(ARFLAGS) $@ $*.o
               rm -f $*.o


    In fact, the .c.a rule listed above is built into make and is unnecessary
    in this example.  A more interesting, but more limited example of an
    archive library maintenance construction follows:

       lib: lib(file1.o) lib(file2.o) lib(file3.o)
               $(CC) -c $(CFLAGS) $(?:.o=.c)
               $(AR) $(ARFLAGS) lib $?
               rm $?
               @echo lib is now up-to-date

       .c.a:;

    Here the substitution mode of the macro expansions is used.  The $? list
    is defined to be the set of object filenames (inside lib) whose C source
    files are out-of-date.  The substitution mode translates the .o to .c.
    Note also, the disabling of the .c.a: rule, which would have created each
    object file, one by one.  This particular construct speeds up archive
    library maintenance considerably.  Also, you can use the double form of
    dependency if the archive library contains a mix of assembly programs and
    C programs:  one dependency for C source files and one for assembly
    source files.

 Files

    [Mm]akefile and s.[Mm]akefile
    /bin/sh

 Notes


    Lines that begin with a tab character are interpreted as shell command
    lines.  If a line that begins with a tab character does not immediately
    follow a dependency line, make will generate a syntax error.


    Some commands return non-zero status inappropriately; use -i, .IGNORE, or
    preprend the command with a ``-'' to overcome the difficulty.


    Filenames which include the characters ``='', ``:'', or ``@'' will not
    work.


    Commands that alter the environment notably cd(C), are ineffectual across
    new-lines in make.


    The argument list to a command executed by make must be less than 5120
    characters minus the length of the environment.  This is a UNIX limita-
    tion.


    The syntax (lib(file1.o file2.o file3.o)) is illegal; you cannot build
    lib(file.o) from file.o.


    Named pipes are not handled well.

 See also

    cc(CP), cd(C), lex(CP), printf(S), sccsfile(FP), sh(C), yacc(CP)

 Standards conformance

    make is conformant with:
    AT&T SVID Issue 2;
    and X/Open Portability Guide, Issue 3, 1989.


Typewritten Software • bear@typewritten.org • Edmonds, WA 98026