make(1) make(1)NAME make - maintain, update, and regenerate groups of files SYNOPSIS make [-b] [-B] [-ddigits] [-e] [-f description-file] [-g] [-i] [-k] [-K] [-n] [-p] [-P] [-q] [-r] [-s] [-t] [-u] [target...] DESCRIPTION make is used to maintain, update, and regenerate groups of files. The make program was designed to manage the sys- tematic regeneration of programs and is typically used, but is not limited to, that purpose. The actions of make are governed by a set of built-in rules. The user can supplement or replace these rules by providing an appropriate description-file. The following is a brief description of all flag options: -b Use compatibility mode for old description files. This mode is on by default. -B Turn off compatibility mode. -ddigits Debug mode. If specified without digits, full debug mode is invoked. If specified with a single digit, the specified debug subset is invoked; -ddigits invokes each specified subset. Currently, subsets 0 and 1 are implemented. -e Cause environment variables to override macro defini- tions within the description file. -f description-file Use the description file specified by description-file. A description file of - (hyphen) denotes the standard input. -g Turn on additional capabilities to automatically checkout SCCS files. See ``SCCS File Handling'' below. -i Ignore any error code that might be returned by a shell command. This mode can also be entered if the target .IGNORE: (see ``Built-in Targets'' below) appears in the description file. -k If a shell command returns a nonzero status, abandon work on the current target, but continue to process other targets that do not depend on the abandoned tar- get. April, 1990 1
make(1) make(1)-K Turn off the -k flag option. The -K flag option is on by default. The -K flag option is most often used in a description file that invokes make, that is a member of a multi-level make hierarchy, and that is invoked by a top-level make with the -k flag option. -n Print the commands in the description file as they would be executed, but do not actually execute them. Even lines beginning with an @ (at sign) are printed (see ``Targets and Dependency Statements'' below). However, if a command line has the string $(MAKE) in it, the line is always executed (see discussion of the $MAKEFLAGS macro under ``Environment Variables and Mac- ros'' below). -p Print out the built-in rules of make, including a com- plete set of macro definitions. -P Search for Pre and Post files (see ``MakeFile'' below) in the directory /usr/lib. For example, for a descrip- tion file named x.mk, make will search for and read /usr/lib/x.mkPre and /usr/lib/x.mkPost. -q Question. The make command returns a zero or a nonzero status code depending on whether or not the target file is up-to-date. -r Do not use the built-in rules of make. To do useful work, this flag option must be accompanied by an ap- propriate description file. -s Silent mode. Do not print command lines before execut- ing them. This mode is also entered if the target .SILENT: appears at any place in the description file. -t touch(1) the target files (causing them to be up-to- date) without executing any commands. -u Look for makecomm and Makecomm files in the user's home directory, as specified by the $HOME environment vari- able, and in the current directory. The search order is $HOME/makecomm, $HOME/Makecomm, ./makecomm and ./Makecomm. At most, one file from each directory is read by make. These files are read before any descrip- tion files and can be used to define macros and rules. Suffix List and Built-in Rules make uses a suffix list and a set of built-in rules to determine how to regenerate a file. The suffix list and the built-in rules are based on the file naming requirements ofrthe various software generation tools in the A/UX environ-ment. For example, a file whose suffix is .s is typically 2 April, 1990
make(1) make(1)an assembly language program that is processed by the as command. A file whose suffix is .c is typically a C program that is processed by the cc command. For example, if make is requested to regenerate a file called x.o, make examines the name of each file in the current directory and looks for all files that have a base name of x and a suffix. In this case, make finds the file x.c and then extracts and saves the suffix, .c. make then prepends the suffix to each member of the default suffix list, one at a time, and attempts to match the resulting string against each built-in rule, from the beginning of the rules to the end. If no match is found, make prepends the suffix to the next element in the suffix list. If no match is ever found, make concludes that it does not know how to regenerate the requested file. When a match is found, make executes the commands that are associated with the matched rule. In this case, the string .c.o matches the .c.o built-in rule. For the .c.o rule, the associated command is cc -O -c base-name.c. make then executes the command, which in this case generates the requested file, x.o. For this version of make, the suffix list is, reading across the columns, .obj .obj~ .for .for~ .pas .pas~ .f .f~ .o .c .c~ .y .y~ .l .l~ .s .s~ .sh .sh~ .h .h~ .i For this version of make, the built-in rules are, reading across the columns, .c .c~ .sh .sh~ .c.o .c~.o .c~.c .s.o .s~.o .c.i .c~.i .c.s .y.o .y~.o .l.o .l~.o .y.c .y~.c .l.c .c.a .c~.a .s~.a .h~.h .f.o .f~.o .p.o .p~.o .for.obj .for~.obj .pas.obj .pas~.obj The suffix list and built-in rules demonstrate three impor- tant features of make. First, the order of the suffix list and the built-in rules is extremely important because the order of both governs which rule will be used to process a file. Second, the built-in rules demonstrate the right-most suffix member of a rule can be empty. This is true for the first April, 1990 3
make(1) make(1)four built-in rules. For example, the .c rule allows make to regenerate the file x, which has no suffix, from the file x.c. Third, both the suffix list and the built-in rules contain the tilde (~) character. To make, the tilde character indi- cates an SCCS file (see sccsfile(4)). Because make was designed to parse suffixes, and SCCS files are identified by their s. prefix, make internally converts references of the form s.filename to filename~. Thus, the rule .c~.o would transform an SCCS C source file into an object file (.o). By definition, a rule starts with a period (.) and cannot contain a slash (/). The format of a rule is: .target:[:] [dependency-list] <tab>[shell-command] . . . where target and at least one colon are required. Items en- closed in square brackets ([]) are optional. Built-in rules cannot rely on another built-in rule to resolve a dependency. Only explicit dependencies can be listed in the dependency list of a rule. Description Files The built-in rules are often supplemented or overriden by the contents of a user-written description file. If the -f flag option is not present, the search order for description files is as shown below: ./makefile ./Makefile ./MakeFile ./s.makefile ./SCCS/s.makefile ./s.Makefile ./SCCS/s.Makefile ./s.MakeFile ./SCCS/s.MakeFile The new description file, MakeFile is described under ``MakeFile Pre- and Post-Processing'' below. If the description file is -, the standard input is taken. More than one -f description-file argument pair may appear on the command line. 4 April, 1990
make(1) make(1)Include Files If the string include or Include appears as the first seven characters of a line in a description file and is followed by a blank or tab character, make assumes that the rest of the line is the name of a description file, which is read by the current invocation of make, after macro substitution. The difference between include and Include is that if in- clude does not exist, make will terminate with an error mes- sage. If Include does not exist, make will continue pro- cessing and will not issue an error message. Targets and Dependency Statements While make can use its built-in rules to perform simple re- generation tasks, make requires direction from the user to accomplish more complicated tasks, such as regenerating a program that is comprised of multiple source files. That direction is provided by the user in a description file from which make reads and processes user-written dependency statements to update one or more targets. The target is usually, but does not have to be, a program. If the depen- dency statement is incomplete, make uses its built-in rules to supplement the dependency statement. The format for a dependency statement is nearly identical to the format for a built-in rule; a distinction is maintained so that if the user wishes to completely replace an existing built-in rule, the user can do so by providing the new rule in the description file. The format of a dependency state- ment is shown below: target [target]:[:] [dependency-list] [;] <tab>shell-command . . . Each target is an alphanumeric string separated by a blank. A target name cannot begin with a tab or a period (.) and cannot contain a colon (:) or a semicolon (;). At least one colon is required; a second colon is optional. The colon must be preceded by at least one target. The dependency-list is a blank-separated list of items on which the target depends. The items can be file names or other targets. The shell-commands are the commands that will be executed to update the target. Each shell command must be preceded by a tab character. If a shell command is so long that it must be spread over two or more lines, the newline, which is automatically placed at the end of the each line by the standard text edi- tors, can be escaped by a backslash (\). April, 1990 5
make(1) make(1)Command lines are executed one at a time, each by its own shell. To have a series of commands executed by the same shell, append a semicolon (;) to the end of each shell com- mand and escape any newlines, as previously described. This treatment of shell commands is particularly important for commands that are executed directly by the shell and whose result is effective only for the lifetime of the shell, such as the cd command. By default, make hands shell commands to the Bourne shell, but if the $SHELL variable is set and exported in the user's environment, make hands shell commands to the specified shell. make interprets the # character as the beginning of a com- ment. When parsing lines in a description file, make deter- mines that the first line that does not begin with a tab or a # begins a new dependency statement or macro definition (see below). The following example illustrates many of the concepts described above. In this dependency statement, the target is a program called pgm. pgm depends on two files a.o and b.o, and they in turn depend on their corresponding source files a.c and b.c and a common file incl.h: # # Making pgm. # pgm: a.o b.o cc a.o b.o -o pgm a.o: incl.h a.c cc -c a.c;\ echo "Done compiling a.c" b.o: incl.h b.c cc -c b.c;\ echo "Done compiling b.c" make updates a target only if its dependents are newer than the target. For this example, make will generate a new a.o if the modification time of either incl.h or a.c is newer than the modification time of a.o or if a.o does not exist. The same is true of b.o. Each line in a description file is terminated by a newline character. In the previous example, a semicolon is appended to the end of the line that invokes the C compiler and the newline is escaped by the a backslash character to pass both the invocation of the C compiler and the echo command to the same instance of the shell. 6 April, 1990
make(1) make(1)Because the built-in rules can be used to determine that a.c and b.c can be used to generate a.o and b.o respectively, the dependency statement for making pgm can be written more briefly: pgm: a.o b.o cc a.o b.o -o pgm a.o b.o: incl.h When parsing shell commands, make first prints the command and then passes everything except the initial tab character directly to the shell as is. The following example uses ``<tab>'' to represent the tab character. <tab>echo a\ <tab>b When processed by make the following output will be pro- duced: <tab>echo a\ <tab>b ab The first and second lines are printed by make before the initial tab character is stripped and the third line is printed by the echo command. Printing of the command before execution can be turned off by preceding each command with the @ character. For exam- ple, if the description file contains @echo a\ b the output of make will be ab Single-Colon and Double-Colon Targets As described in the format for a dependency statement above, a dependency statement must have at least one colon, but may have an optional second colon. For the following dependency statement a: b.o a: c.o a: d.o make concludes that a depends on b.o, c.o, and d.o. That is, the preceding dependency statements are equivalent to April, 1990 7
make(1) make(1)a: b.o c.o d.o make treats dependency statements that have two colons dif- ferently so that a description file that contains a:: b.o a:: c.o a:: d.o contains three distinct and separate dependency statements. Whether a single-colon or double-colon rule, the target is updated whenever one of the following conditions is true: Single-Colon if any dependent is newer than the target, or if the target does not exist Double-Colon if any dependent is newer than the target, or if the target does not exist, or if the target does not have a dependency list Double-colon dependency statements are useful for those si- tuations where a single target name is desired, but depend- ing on the context, different commands need to be executed to update the target. For example: a:: a.sh cp a.sh a a:: a.c cc -o a a.c The first dependency statement is executed if the current directory contains the file a.sh, and the second dependency statement is executed if the current directory contains the file a.c. If both a.sh and a.c exist in the current direc- tory, one or both target statements could be executed depending on whether the target is older than the depen- dents. If the target is missing, the target is considered to be older than the dependents. Double-colon dependency statements are also useful for situ- tations in which a target has the same name as a subdirecto- ry in the current directory. For example, if the dependency statement is mail: cd mail;\ cc mail.o -o mail and the current directory contains a directory called mail, 8 April, 1990
make(1) make(1)the commands to update the target will never be invoked. This is because make assumes that if the target mail exists (even if it is a directory) and has no dependency list, the target is up-to-date. As a result, the target name in single-colon dependency statement should never be the name of a subdirectory in the current directory. Often, however, assigning the target the same name as the directory that contains the files on which the target depends makes the description file more meaningful to the user. make processes double-colon dependency statements differently so that, mail:: cd mail;\ cc mail.o -o mail works as desired. This is because if a double-colon depen- dency statement has no dependency list, make processes the commands that up-date the target even if the target already exists. The caveat is, however, that make always recompiles mail.c even when the executable mail is newer than mail.c. A better solution to this problem is described under ``At- tributes'' below. As mentioned earlier, the user can replace a built-in rule by providing a new rule of the same name in the description file. The user can also disable a built-in rule as shown by the following example: .c.a:; make interprets a semicolon (;) that is not preceded by a command as a null command, which has the effect of disabling the specified rule. Just as the built-in rules can be replaced, so can the de- fault suffix list. The following line in a description file clears the suffix list: .SUFFIXES: The following line appends additional suffixes to the end of the existing suffix list: .SUFFIXES: .n .x Multiple suffix lists accumulate until cleared, as shown above, or make terminates. Built-in Targets The targets described in this section are actually built-in rules that enabled by the user by including them in a April, 1990 9
make(1) make(1)description file. If present, they modify the default behavior of make. Because make reads the entire description file before beginning to process dependency statements, the following built-ins, which must appear at the beginning of a line, are processed first, whether they appear at the begin- ning, middle, or end of the description file. .DEFAULT: If a file must be made but there are no explicit shell commands or relevant built-in rules, the shell commands listed under .DEFAULT: are used. .IGNORE: If present, .IGNORE has the same effect as the -i flag option, which is to ignore nonzero return codes from commands. .PRECIOUS: The default behavior of make is to remove a target and its dependents when a quit or interrupt signal is re- ceived while processing the commands that update the target. Because the actions of make depend in large part on the mere existence of a file, removal of poten- tially incomplete files helps ensure that the proper files are regenerated each time. Removal can be avoid- ed by making specific files dependent on .PRECIOUS:. See ``Error Handling'' below for further details. .MAKESTOP [ exit-code ]: If present, .MAKESTOP: causes make to exit. .MAKESTOP: is useful in a multi-level directory and description file hierarchy to quickly by-pass a make in a particu- lar directory or directories. exit-code is optional and defaults to zero if not specified. If no exit code is specified or if the specified exit code is zero, make exits silently. If a nonzero exit code is speci- fied, make prints a warning message. .SILENT: If present, .SILENT: has the same effect as the -s command line flag option. Environment Variables and Macros The documentation for make uses the term macro to name the entities that the shell documentation calls environment variables. A macro is a variable whose value is set in a description file and can be overridden from the make command line. Although make and the shell use these entities in nearly identical ways, there are differences, which are described below. 10 April, 1990
make(1) make(1)The following sample shell script NAME=Joe echo NAME echo $NAME produces the following result NAME Joe The difference between the first and second echo commands is that first simply requests that the string NAME be echoed, while the second, by the prepended dollar sign ($) requests that the contents of NAME be echoed. Such a request is called expansion. Expansion is handled differently in make. The following ex- ample description file NAME=joe all: echo NAME echo $NAME produces the following result NAME AME This is because make requires that macro names that are longer than one character be enclosed by parentheses or braces for expansion to occur. In this case, make sees the $ and attempts to expand a variable named N. No such vari- able is set, so nothing is echoed and the echo command com- pletes by echoing AME. The following description file pro- duces the desired result: NAME=joe all: echo NAME echo $(NAME) The use of braces is equivalent to the use of parentheses, so that ${NAME} is equivalent to $(NAME). Each time make evaluates a macro, make strips one dollar sign ($) from it. Therefore, an extra dollar sign should be prepended to any macro that is part of a shell command line. When make is invoked, make reads the user's environment and April, 1990 11
make(1) make(1)makes all the variables found there available for modifica- tion by the description file. Environment variables are processed before any description file and after the built-in rules; macro definitions in a description file override environment variables of the same name. The -e flag option causes environment variables to override macro definitions of the same name in a description file. The formal definition of a macro is shown below: macro-name = string2 By convention, macro names are upper-case. macro-name is an alphanumeric string that cannot contain a colon (:) or a semicolon (;). The equal sign (=) can be surrounded by spaces or tabs. string2 is defined as all characters up to a comment character or an unescaped newline. make provides several built-in macros. These macros are described below: MAKEFLAGS If not present in the environment, make creates the MAKEFLAGS macro and assigns to it the flag options with which make was invoked. MAKEFLAGS is processed by make as containing any legal input flag option (except -f, -p, -P, -r, and -u) Thus, MAKEFLAGS always contains the current input flag options. This proves very useful for ``super-makes''. In fact, as noted above, when the -n flag 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 ex- ecuted. 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 description files for a software project without actually causing the execution of update commands. MAKELEVEL If not present in the environment, make creates the MAKELEVEL macro, assigns an initial value of zero, and exports it. If already present in the environment, make increments the value of MAKELEVEL by one. In this way, each subordinate invocation of make can know its level in a multi-level make hierarchy. This macro is read-only and cannot be modified by the description file. MAKEBDIR If not present in the environment, make creates the 12 April, 1990
make(1) make(1)MAKEBDIR macro and assigns to it the absolute pathname of the current directory. If already present in the environment, the value of MAKEBDIR is not changed. MAKEBDIR provides a way for each subordindate invoca- tion of make to obtain the pathname of the top-level make. MAKEGOALS For every invocation of make, make creates the MAKEGOALS macro and assigns to it the targets that were specified on the command line. For the command line, $ make clean all clobber MAKEGOALS will be set to ``clean all clobber''. If the current invocation of make invokes make, the invocation can be made as shown in the following example: MAKE=make cd dir; $(MAKE) $(MAKEGOALS) In this way, the same command line arguments can be passed to subordinate invocations of make. VPATH This version of make supports special processing of macro VPATH, if set. VPATH is useful for processing files that are located in a directory other than the current directory. In the following example, main.c is located in the current directory. func1.c is located in ../common, and func2.c is located in ../incl. make will search the directories specified by the VPATH variable for any dependencies that are not in the current directory. VPATH=../common:../incl main: main.o func1.o func2.o cc -o $@ $> In this example, $@ (described below) expands to the target name and $> (described below) expands to the list of dependencies on the current target. If main.c, func1.c, or func2.c are not present in the current directory, make will use its built-in rules to search for SCCS versions of the files in the current directory (see ``SCCS File Handling'' below). If SCCS versions of the files are not found, make will search the path- names specified by VPATH. The following built-in macros define values for common software generation programs or flag options to those pro- grams. Description files can replace or supplement the April, 1990 13
make(1) make(1)values of these macros to change the way in which the built-in rules work: AR This macro is defined as ar. AS This macro is defined as as. ASFLAGS This macro is defined as null and is provided as an ar- gument to the assembler. CC This macro is defined as cc. CFLAGS This macro is defined as -O and is provided as an argu- ment to the C compiler. CHMOD This macro is defined as chmod. CP This macro is defined as cp. F77 This macro is defined as f77. F77FLAGS This macro is defined as null and is provided as an ar- gument to the FORTRAN compiler. FORTRAN This macro is defined as fortran. FORTRANFLAGS This macro is defined as null and is provided as an ar- gument to the FORTRAN compiler. GET This macro is defined as get and is used to get SCCS versions of files. GFLAGS This macro is defined as null and is provided as an ar- gument to get. LD This macro is defined as ld. LDFLAGS This macro is defined as null and is provided as an ar- gument to ld. LEX This macro is defined as lex. LFLAGS This macro is defined as null and is provided as an ar- 14 April, 1990
make(1) make(1)gument to lex. MAKE This macro is defined as make. MV This macro is defined as mv. PASCAL This macro is defined as pascal. PASCALFLAGS This macro is defined as null and is provided as an ar- gument to pc. PC This macro is defined as pc. PCFLAGS This macro is defined as null and is provided as an ar- gument to pc. RM This macro is defined as rm. YACC This macro is defined as yacc. YFLAGS This macro is defined as null and is provided as an ar- gument to yacc. The following six built-in macros have special expansion capabilities that are useful for writing shell commands. * The * macro stands for the file name part of the current dependent with the suffix deleted. It is evaluated only for built-in rules. @ The @ macro stands for the full target name of the current target. It is evaluated only for explicitly- named dependencies. < The < macro is evaluated only for built-in rules or the .DEFAULT rule. It is the module that is out-of-date with respect to the target (i.e., 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 $< April, 1990 15
make(1) make(1)? The ? macro is evaluated when explicit rules from the description file are evaluated. It is the list of prerequisites that are out of date with respect to the target; essentially, those modules that must be re- built. % The % macro is only evaluated when the target is an ar- chive library member of the form lib(file.o). In this case, @ evaluates to lib and % evaluates to the library member, file.o. > The > macro is expanded to list all the dependencies on the current rule. These six macros can have alternative forms. When an upper case D or F is appended to any of the six macros, the mean- ing 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. The following description file demonstrates the use of the ? and > macros in their standard and alternate forms: pgm: @echo "? = $?" @echo "?D = $(?D)" @echo "?F = $(?F)" @echo "> = $>" @echo ">D = $(>D)" @echo ">F = $(>F)" pgm: dir/a.o pgm: dir/b.o pgm: dir/c.o When a.o is the only object that is newer than the pgm, the following is output from make: ? = dir/a.o ?D = dir ?F = a.o > = dir/a.o dir/b.o dir/c.o >D = dir dir dir >F = a.o b.o c.o Macro Substitution The contents of a macro can be substituted as shown below: $(macro-name [: subst1 =[ subst2]]) are replaced by string2, which is delimited by blanks, tabs, 16 April, 1990
make(1) make(1)newline characters and the beginning of lines. A substitute sequence can only replace the trailing characters of subst1. For example, SAMPLE=/a/b/file.test all: @echo "1 $(SAMPLE:file=FILE)" @echo "2 $(SAMPLE:test=TEST)" @echo "3 $(SAMPLE:a/=A/)" @echo "4 $(SAMPLE:b/file.test=K)" @echo "5 $(SAMPLE:a=A) has the following output 1 /a/b/file.test 2 /a/b/file.TEST 3 /a/b/file.test 4 /a/K 5 /a/b/file.test In the above example, only the second and fourth examples are successful. The other examples fail because they do not substitute the trailing characters of the expanded macro. The following example demonstrates the usefulness of string substitution: all: /u/test/a.o cc -S $(?:a=.c) mv $(?:.o=.s) .tmp sed "s/text/data/" > $(?:.o=.s) < .tmp as -o $@ $(?:.o=.s) rm .tmp The above example uses the @ (expand to the full target name of the current target) and the ? (expand to the list of out-of-date dependencies) macros to produce the assembly language file for each dependent of the all target, change each occurrence of text to data using sed, and assemble each resulting .s file. Substitution works only on macros that are part of shell command lines. This version of make does not support sub- stitutions of macros that are part of dependency lists. Macro Testing This version of make supports the testing of macros, where the format is: $(macro-name:test-operator) April, 1990 17
make(1) make(1)The macro name may be set or unset and with or without an assigned value. The test-operator can be one of the follow- ing: L The macro is expanded to the length of it's contents. An empty or null value expands to zero. This test operator is useful for determining whether or not to examine the contents of a macro. V If the macro is set and has a non-null value, the macro is expanded to null; otherwise, the macro is expanded to #. This test can be used to control the execution of command lines as shown below: $(macro-name:V)conditional-command If the macro is not set, the macro is expanded to #, which causes make to evaluate the line as a comment. As a result, conditional-command is not executed. N If the macro is set and has a non-null value, the macro is expanded to #; otherwise, the macro is expanded to null. This is the opposite of the V test operator described above and is used in the same way as the V test operator. For example, assume the desire to have a target called clean if the macro $CLNFILES is set. The dependency statement would remove the files expanded from this macro. Here is how the dependency statement would look: $(CLNFILES:V)clean: $(CLNFILES:V) @echo "Removing: $(CLNFILES)";\ rm -f $(CLNFILES) If the $CLNFILES macro is set and contains a non-null value, the $(CLNFILES:V) macro will be nulled out when make reads the description file, and the line is be processed just as if the description file contained: clean: @echo "Removing: $(CLNFILES)";\ rm -f $(CLNFILES) The $(CLNFILES) macro is expanded just before the command line is executed. Macros that have test operators are ex- panded during the parsing of the command line. This means that the order of macros that have test operators is signi- ficant, which is unlike the normal behavior of macros that do not have test operators. Normal macros are expanded after all description files have been read and command line execution has begun. Expansion of macros that have test 18 April, 1990
make(1) make(1)operators can be delayed by prefixing more $ characters, just as can be done with normal macros. In the example above, notice that $(CLNFILES:V) does not ap- pear in front of each line. This is because a single com- mand line was used, and that command line was spread over two lines, with the newline escaped by the backslash (\) character. If there had been multiple command lines, each command line would have to have been preceded by a $(CLNFILES:V) macro. Global Macros This version of make provides special handling of user- defined macros that begin with G_. Such macros are automat- ically exported to the environment, so they can be easily passed to subordinate invocations of make. Default Macro Values This version of make supports a default expansion value for non-existent or null-valued macros. The default value is specified as shown below: $(XYZ::default) In this case, if the macro XYZ is not defined or has a null value, it is expanded to default. The default value is res- tricted to a single word, so the following example will not have the intended result $(XYZ::This is the default) Instead, XYZ is expanded to This. But the following example will work: DEFAULT = This is the default all: @echo "$(NOTDEFINED::$(DEFAULT))" Pattern Matching on Macros This version of make supports limited shell-style pattern matching on macros. For example, cc -o $@ $(>:=*.o) Each word in the expanded > macro is tested (shell-style) against the asterisk (*) pattern and compiled on a match. Attributes This version of make understands attributes, which can be placed before or after the dependents in a dependency list April, 1990 19
make(1) make(1)as shown below: target: [attributes] [dependents] [attributes] Attributes can be any of: .FAKE If the target exists and has no dependents, the normal behavior of make for single-colon dependency statements is to do nothing. The addition of the .FAKE attribute to the dependency statement requires make to treat the target is if it did not exist. This, in turn, forces make to execute the associated commands. .CURTIME This attribute causes make to use the current time rather than the most recent modification time of the target, even if the target does not exist. This attri- bute is used with the .FAKE attribute to prevent the associated dependency statement from being invoked un- less the dependents have been up-dated with a newer time. .MAIN The normal behavior of make when invoked without a tar- get name on the command line is to search the descrip- tion file for the first target, process the target, and then terminate. The addition of .MAIN to a dependency statement causes make to treat the associated dependen- cy statement as if it were the first dependency state- ment in the description file. .PRE This attribute informs make that the associated target is to be made before any others, including .MAIN. Hence, this attribute can be used to place initializa- tion commands. Because the entire description file is read before the targets are processed, the placement of this attribute is position-independent within the description file. .POST This attribute informs make that the associated target is to be processed after all others. Hence, this at- tribute can be used to place cleanup commands. .KEEPTIME This attribute causes make to maintain the target's original modification time, even after the target has been regenerared. .OLDTIME This attribute causes make to ignore the target's 20 April, 1990
make(1) make(1)modification time and apply a modification time of 0 for the purpose of determining if the target should be up-dated. After the target is regenerated, make sets the correct modification time. .NOVPATH This attribute causes make to ignore the $VPATH macro for the associated target. If targets that have .MAIN, .PRE, and .POST attributes are dependents of other targets, the targets are made in the order dictated by the dependencies and not by the attri- butes. Attributes on double-colon dependency statements apply to all of them as a unit. 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 li- brary that contains file.o. (This assumes the LIB macro has been previously defined.) The expression $(LIB)(file1.o file2.o) is not legal. The built-in rules pertaining to ar- chive libraries have the form .suffix.a where suffix is the suffix from which the archive member is to be made. An un- fortunate by-product of the current implementation requires suffix 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 in- terface 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 rv $@ $*.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 con- struction follows: lib: lib(file1.o) lib(file2.o) lib(file3.o) $(CC) -c $(CFLAGS) $(?:.o=.c) ar rv lib $? rm $? April, 1990 21
make(1) make(1)@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 file names (inside lib) whose C source files are out-of-date. The sub- stitution mode translates the .o to .c. (Unfortunately, one cannot as yet transform to .c~; however, this may become possible in the future.) Note also, the disabling of the .c.a: built-in rule, which would have created each object file, one by one. This particular construct speeds up ar- chive library maintenance considerably. This type of con- struct becomes very cumbersome if the archive library con- tains a mix of assembly programs and C programs. MakeFile Pre- and Post-Processing If, by its search rules, make finds a description file named MakeFile or SCCS/s.MakeFile, the files /usr/lib/MakeFilePre and /usr/lib/MakeFilePost, if present, are read. If, for example, the description file is named x.mk and the -P flag option is specified, make will read /usr/lib/x.mkPre and /usr/lib/x.mkPost, if present. The pre- and post-processing files are description files that can be used to store global environmental settings and rules for events that the user would like to occur prior to and after processing of a description file. If the macro G_SGS_ROOT is present in the environment, make considers this to be the root for finding the pre- and post-processing files. For example, if G_SGS_ROOT is set to newroot, make will look for the pre- and post-processing files in the directory /newroot/usr/lib. SCCS File Handling As described in ``Description Files'' above, make can check-out read-only copies of makefile, Makefile, or MakeFile from an SCCS version of the file in the current directory or an SCCS version of the file located in a sub- directory named SCCS. This ability is separate from the built-in rules that govern the check-out of SCCS versions of dependents and is not turned off by the -r flag option to make. The built-in rules for dependents can only check-out a file for which there is an SCCS version in the current directory; the built-in rules cannot check-out an SCCS version of a file located in a subdirectory named SCCS. If the -g option is used, however, and the file does not ex- ist in the current directory, make will first use its built-in rules to check-out the file in the current directo- 22 April, 1990
make(1) make(1)ry. If this attempt fails because the SCCS version does not exist, the -g flag option causes make to again search the current directory and then a subdirectory named SCCS, if present, and check out the file if found. Note that the current directory is searched twice, once by the built-in rules and once because the -g flag option was specified. Searching the current directory makes the -g flag option especially useful with the -r flag option. The -r flag op- tion turns off the built-in rules, and, thus, when used with the -g flag option, the current directory is search just once. If a VPATH variable is present and set, the built-in rules are used to search the specified directories for SCCS ver- sions of the file. If the -g flag option is specified, any subdirectories named SCCS in the VPATH directories are also searched. The built-in rules for checking out dependents from their SCCS versions in the current directory are not used to pro- cess include files (see ``Include Files'' above). If the include file exists only in its SCCS version in the current directory, make will not check it out. If make is invoked with the -g flag option, however, make will check out an in- clude file if it is present in an SCCS version in the current directory or in a subdirectory named SCCS. In no case does make check out a copy of a description file, an include file, or a dependent file if the file already ex- ists. If a file is checked out by the built-in rules, make does not remove the checked out copy. If a file is checked out by the action of the -g flag option, the checked-out copy is automatically removed when no longer needed. Error Handling Shell commands that return a nonzero status normally ter- minate make. This behavior can be modified in a number of ways: -i If present on the command line, this flag option causes make to ignore any nonzero status that is returned by a shell command and to continue processing the current description file. .IGNORE: See ``Built-in Targets''. -k If present on the command line, this flag option causes make, to abandon work on the current target if a shell command returns a nonzero status. make will continue April, 1990 23
make(1) make(1)work on other targets in the description file that do not depend on the target for which the error was re- ceived. - If prepended to any shell command, make will not ter- minate on an error that might occur as a result of exe- cuting the command, but will continue processing the description file. The - can be combined with the pre- viously described @ symbol, which suppresses the print- ing of the command before it is passed to the shell. The combination can be either -@ or @-. Both error messages returned by the shell and make's standard er- ror messages are still printed. As mentioned earlier, make removes a target and its depen- dents when a quit or interrupt signal is received. The fol- lowing conditions apply: 1) The dependency statement must be a single-colon dependency statement. If the dependency statement is a double-colon dependency statement, make does not remove files. 2) The target must have existed before processing of the dependency statement began. 3) The target is not a dependent of the built-in tar- get .PRECIOUS:. 4) make was not invoked with the -n flag option. 5) make was not invoked with the -t flag option. The standard termination message due to a nonzero status code is shown below. In this case, make terminates because the description file, x.mk, does not exist in the directory /dir. $ make -f x.mk Make: Cannot read description file /dir/x.mk Make: Stopped in directory /dir. FILES /bin/make /usr/lib/description-filePre /usr/lib/description-filePost $HOME/[Mm]akecomm [Mm]akecomm s.[Mm]ake[Ff]ile SCCS/s.[Mm]ake[Ff]ile 24 April, 1990
make(1) make(1)SEE ALSO cc(1), cd(1), csh(1), ksh(1), lex(1), sh(1), touch(1), yacc(1), printf(3S), sccsfile(4). ``make Reference'' in A/UX Programming Languages and Tools, Volume 2. BUGS The syntax (lib(file1.o file2.o file3.o) is illegal. You cannot build lib(file.o) from file.o. The macro $(a:.o=.c~) does not work. April, 1990 25