Programming Utilities Guide

make Enhancements Summary

The following summarizes additional new features to make.

Default Makefile

make's implicit rules and macro definitions are no longer hard-coded within the program itself. They are now contained in the default makefile /usr/share/lib/make/make.rules. make reads this file automatically unless there is a file in the local directory named make.rules. When you use a local make.rules file, you must add a directive to include the standard make.rules file to get the standard implicit rules and predefined macros.

The State File .make.state

make also reads a state file, .make.state, in the directory. When the special-function target .KEEP_STATE is used in the makefile, make writes out a cumulative report for each target containing a list of hidden dependencies (as reported by compilation processors such as cpp) and the most recent rule used to build each target. The state file is very similar in format to an ordinary makefile.

Hidden-Dependency Checking

When activated by the presence of the .KEEP_STATE target, make uses information reported from cc, cpp, f77, ld, make, pc and other compilation commands and performs a dependency check against any header files (or in some cases, libraries) that are incorporated into the target file. These "hidden" dependency files do not appear in the dependency list, and often do not reside in the local directory.

Command-Dependency Checking

When .KEEP_STATE is in effect, if any command line used to build a target changes between make runs (either as a result of editing the makefile or because of a different macro expansion), the target is treated as if it were out of date; make rebuilds it (even if it is newer than the files it depends on).

Automatic Retrieval of SCCS Files

This section discusses the rule for the automatic retrieval of files under sccs.

Tilde Rules Superseded

This version of make automatically runs sccs get, as appropriate, when there is no rule to build a target file. A tilde appended to a suffix in the suffixes list indicates that sccs extraction is appropriate for the dependency file. make no longer supports tilde suffix rules that include commands to extract current versions of sccs files.

To inhibit or alter the procedure for automatic extraction of the current sccs version, redefine the .SCCS_GET special-function target. An empty rule for this target entirely inhibits automatic extraction.

Pattern-Matching Rules

Pattern-matching rules have been added to simplify the process of adding new implicit rules of your own design. A target entry of the form:

tp%ts : dp%ds
      rule

defines a pattern-matching rule for building a target from a related dependency file. tp is the target prefix; ts, its suffix.dp is the dependency prefix; ds, its suffix. The % symbol is a wild card that matches a contiguous string of zero or more characters appearing in both the target and the dependency file name. For example, the following target entry defines a pattern-matching rule for building a troff output file, with a name ending in .tr from a file that uses the -ms macro package ending in .ms:

%.tr: %ms
troff -t -ms $< > $@

With this entry in the makefile, the command:

make doc.tr

produces:

$ make doc.tr 
troff -t -ms doc.ms > doc.tr

Using that same entry, if there is a file named doc2.ms, the command:

make doc2.tr

produces:

$ make doc2.tr 
troff -t -ms doc2.ms > doc2.tr

An explicit target entry overrides any pattern-matching rule that might apply to a target. Pattern-matching rules, in turn, normally override implicit rules. An exception to this is when the pattern-matching rule has no commands in the rule portion of its target entry. In this case, make continues the search for a rule to build the target, and uses as its dependency the file that matched the (dependency) pattern.

Pattern-Replacement Macro References

As with suffix rules and pattern-matching rules, pattern-replacement macro references have been added to provide a more general method for altering the values of words in a specific macro reference than that already provided by suffix replacement in macro references. A pattern-replacement macro reference takes the form:

$ (macro :p %s =np %ns )

where p is an existing prefix (if any), s is an existing suffix (if any), np and ns are the new prefix and suffix, and % is a wild card character matching a string of zero or more characters within a word.

The prefix and suffix replacements are applied to all words in the macro value that match the existing pattern. Among other things, this feature is useful for prefixing the name of a subdirectory to each item in a list of files. For instance, the following makefile:

SOURCES= x.c y.c z.c 
SUBFILES.o= $(SOURCES:%.c=subdir/%.o) 

all: 
        	@echo $(SUBFILES.o)

produces:

$ make 
subdir/x.o subdir/y.o subdir/z.o

You can use any number of % wild cards in the right-hand (replacement) side of the = sign, as needed. The following replacement:

...
NEW_OBJS= $(SOURCES:%.c=%/%.o)

would produce:

...
x/x.o y/y.o z/z.o

Pattern-replacement macro references should not appear on the dependency line of a pattern-matching rule's target entry. This produces unexpected results. With the makefile:

OBJECT= .o 

x: 
%: %.$(OBJECT:%o=%Z) 
        	cp $< $@

it appears that make should attempt to build a target named x from a file named x.Z. However, the pattern-matching rule is not recognized; make cannot determine which of the % characters in the dependency line apply to the pattern-matching rule and that apply to the macro reference.

Consequently, the target entry for x.Z is never reached. To avoid problems like this, you can use an intermediate macro on another line:

OBJECT= .o 
ZMAC= $(OBJECT:%o=%Z) 

x: 
%: %$(ZMAC) 
        	cp $< $@

New Options

The new options are:

-d

Displays dependency-check results for each target processed. Displays all dependencies that are newer, or indicates that the target was built as the result of a command dependency.

-dd

Performs the same function as -d in earlier versions of make. Displays a great deal of output about all details of the make run, including internal states, and so forth.

-D

Displays the text of the makefile as it is read.

-DD

Displays the text of the makefile and of the default makefile being used.

-p

Prints macro definitions and target entries.

-P

Reports all dependencies for targets without rebuilding them.

Support for C++ and Modula-2

This version of make contains predefined macros for compiling C++ programs. It also contains predefined macros and implicit rules for compiling Modula-2.

Naming Scheme for Predefined Macros

The naming scheme for predefined macros has been rationalized, and the implicit rules have been rewritten to reflect the new scheme. The macros and implicit rules are upward compatible with existing makefiles.

Some examples include the macros for standard compilations commands:

LINK.c

which is a standard cc command line for producing executable files.

COMPILE.c

which is a standard cc command line for producing object files.

New Special-Purpose Targets

.KEEP_STATE

When included in a makefile, this target enables hidden dependency and command-dependency checking. In addition, make updates the state file .make.state after each run.


Note -

The .KEEP_STATE target should not be removed if it has been used in a make run.


.INIT and .DONE

These targets can be used to supply commands to perform at the beginning and end of each make run.

.FAILED

The commands supplied are performed when make fails.

.PARALLEL

These can be used to indicate which targets are to be processed in parallel, and which are to be processed in serial fashion.

.SCCS_GET

This target contains the rule for extracting current versions of files from sccs history files.

.WAIT

When this target appears in the dependency list, make waits until the dependencies that precede it are finished before processing those that follow, even when processing is parallel.

New Implicit lint Rule

Implicit rules have been added to support incremental verification with lint.

Macro Processing Changes

A macro value can now be of virtually any length. Whereas in earlier versions only trailing white space was stripped from a macro value, this version strips off both leading and trailing white space characters.

Macros: Definition, Substitution, and Suffix Replacement

New Append Operator

+=

This is the new append operator that appends a SPACE followed by a word or words, onto the existing value of the macro.

Conditional Macro Definitions

:=

This is the conditional macro definitions operator that indicates a conditional (targetwise) macro definition. A makefile entry of the form:

target := macro = value

indicates that macro takes the indicated value while processing target and its dependencies.

Patterns in Conditional Macros

make recognizes the % wild card pattern in the target portion of a conditional macro definition. For instance:

profile_% := CFLAGS += -pg

would modify the CFLAGS macro for all targets having the `profile_' prefix. Pattern replacements can be used within the value of a conditional definition. For instance:

profile_% := OBJECTS = $(SOURCES:%.c=profile_%.o)

applies the profile_ prefix and .o suffix to the basename of every .c file in the SOURCES list (value).

Suffix Replacement Precedence

Substring replacement now takes place following expansion of the macro being referenced. Previous versions of make applied the substitution first, with results that were counterintuitive.

Nested Macro References

make now expands inner references before parsing the outer reference. A nested reference as in this example:

CFLAGS-g = -I../include
  OPTION = -g
  $(CFLAGS$(OPTION))

now yields the value -I../include , rather than a null value, as it would have in previous versions.

Cross-Compilation Macros

The predefined macros HOST_ARCH and TARGET_ARCH are available for use in cross-compilations. By default, the arch macros are set to the value returned by the arch command.

Shell Command Output in Macros

A definition of the form:

MACRO :sh = command

sets the value of MACRO to the standard output of the indicated command, NEWLINE characters being replaced with SPACE characters. The command is performed just once, when the definition is read. Standard error output is ignored, and make halts with an error if the command returns a non-zero exit status.

A macro reference of the form:

$(MACRO :sh)

expands to the output of the command line stored in the value of MACRO, whenever the reference is evaluated. NEWLINE characters are replaced with SPACE characters, standard error output is ignored, and make halts with an error if the command returns a non-zero exit status.

Improved ar Library Support

make automatically updates an ar-format library member from a file having the same name as the member. Also, make now supports lists of members as dependency names of the form:

lib.a: lib.a(member member ...)

Target Groups

It is now possible to specify that a rule produces a set of target files. A + sign between target names in the target entry indicates that the named targets constitute a group. The target group rule is performed once, at most, in a make invocation.