make(1) make(1)NAME make - maintains, updates, and regenerates groups of files SYNOPSIS make [-a] [-b] [-B] [-ddigits] [-e] [-f description-file] [-g] [-G] [-i] [-k] [-K] [-M] [-n] [-p] [-P] [-q] [-r] [-s] [-t] [-u] [-V] [target]... ARGUMENTS -a Updates all targets as if they were all out-of-date. This option is useful for completely rebuilding all files. -b Uses compatibility mode for old description files. This mode is on by default. -B Turns off compatibility mode. -ddigits Specifies debug mode. If you specify this option without a digits argument, full debug mode is invoked. If you specify this option with a single digit, the specified debug subset is invoked; this option invokes each specified subset. Currently, subsets 0 and 1 are implemented. -e Causes environment variables to override macro definitions within the description file. -f description-file Uses the description file specified by description-file. A description file of - (hyphen) denotes the standard input. -g Turns on additional capabilities to automatically check-out Source Code Control System (SCCS) files. See ``SCCS File Handling'' in the ``Description'' section, later in this manual page. -G Enables the Dynamic Include File Dependency Generation (DIFDG). You can also enable DIFDG by defining the variable MAKEDIFDGSUFFIXES as a list of legal suffixes for the source files to be searched. -i Ignores any error code that might be returned by a shell command. This mode can also be entered if the target .IGNORE: appears in the description file. (See ``Built-in Targets'' in the ``Description'' section, later in this manual page.) -k Causes make to abandon work on the current target, but continues to process other targets that do not depend January 1992 1
make(1) make(1)on the abandoned target, if a shell command returns a nonzero status. -K Turns off the -k option. This option is on by default. This option is most often used in a description file that invokes make, which is a member of a multilevel make hierarchy, and that is invoked by a top-level make command with the -k option. -M Stores the dependency map for all object files in a file. The default name for this file is ._Make_State. (You can change the default name by changing the value in the MAKEDEPFILE variable to the desired name.) You can also enable this option by defining the variable MAKEDEPFILE as the name of the file in which you want to store the map. -n Prints the commands in the description file as they would be executed, but does not actually execute them. Even lines beginning with an @ (at sign) are printed. (See ``Targets and Dependency Statements'' in the ``Description'' section, later in this manual page.) However, if a command line has the string $(MAKE) in it, the line is always executed. (See discussion of the $MAKEFLAGS macro in ``Environment Variables and Macros,'' in the ``Description'' section.) -p Prints out the built-in rules of make, including a complete set of macro definitions. -P Searches for Pre and Post files in the directory /usr/lib. (See ``MakeFile Preprocesing and Postprocessing'' in the ``Description'' section.) For example, for a description file named x.mk, make will search for and read /usr/lib/x.mkPre and /usr/lib/x.mkPost. -q Specifies a 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 Causes make not to use its built-in rules. To do useful work, this option must be accompanied by an appropriate description file. -s Specifies silent mode. Does not print command lines before executing them. This mode is also entered if the target .SILENT: appears at any place in the description file. -t Touches the target files (causing them to be up-to- date) without executing any commands. 2 January 1992
make(1) make(1)target Specifies the program to be run. -u Looks for makecomm and Makecomm files in the user's home directory, as specified by the $HOME environment variable, 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 description files and can be used to define macros and rules. -V Displays the current version of make. DESCRIPTION make is used to maintain, update, and regenerate groups of files. The make program was designed to manage the systematic regeneration of programs and is typically used for, but is not limited to, that purpose. The actions of make are governed by a set of built-in rules. You can supplement or replace these rules by providing an appropriate description-file. Suffix List and Built-in Rules The make command 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 of the various software generation tools in the A/UX environment. For example, a file whose suffix is .s is typically 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 first to the last. 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. The make command then executes the command, which in this case generates the requested file, x.o. January 1992 3
make(1) make(1)For this version of make, the suffix list is as follows, 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 as follows, 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 important 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 that the rightmost suffix member of a rule can be empty. This is true for the first 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 indicates 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 4 January 1992
make(1) make(1)enclosed in square brackets ([]) are optional. A built-in rule 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 overridden by the contents of a user-written description file. If the -f option is not present, the search order for description files is as follows: ./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 in ``MakeFile Preprocessing and Postprocessing'' later in the ``Description'' section. If the description file is -, the standard input is taken. More than one -f description-file argument pair can appear on the command line. 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 include does not exist, make will terminate with an error message. If Include does not exist, make will continue processing and will not issue an error message. Targets and Dependency Statements Although make can use its built-in rules to perform simple regeneration tasks, make requires direction from the user to accomplish more complicated tasks, such as regenerating a program that comprises multiple source files. You provide that direction 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 a dependency statement is incomplete, make uses its built-in rules to supplement the dependency statement. January 1992 5
make(1) make(1)The format for a dependency statement is nearly identical to the format for a built-in rule; a distinction is maintained so that if you want to completely replace an existing built-in rule, you can do so by providing the new rule in the description file. The format of a dependency statement is as follows: target [target]:[:] [dependency-list] [;] <tab>shell-command . . . Each target argument 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 argument is a blank-separated list of items on which the target depends. The items can be filenames or other targets. The shell-command arguments 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 extends over two or more lines, you can escape the newline character, which is automatically placed at the end of the each line by the standard text editors, by preceding it with a backslash (\). 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 command and escape any newlines, as just described. This treatment of shell commands is particularly important for any command that is 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. The make command interprets the number sign (#) as the beginning of a comment. When parsing lines in a description file, make determines that the first line that does not begin with a tab or a # begins a new dependency statement or macro definition. (Macros are discussed later in the ``Description'' section.) The following example illustrates many of the concepts described here. In this dependency statement, the target is 6 January 1992
make(1) make(1)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" The make command updates a target only if its dependents are newer than the target. For this example, make will generate a new a.o file 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 a backslash character to pass both the invocation of the C Compiler and the echo command to the same instance of the shell. 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 this example is processed by make, the following output will be produced: <tab>echo a\ <tab>b ab January 1992 7
make(1) make(1)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. You can turn off printing of the command before execution by preceding each command with the @ character. For example, 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 earlier, a dependency statement must have at least one colon, and can have an optional second colon. For the dependency statement a: b.o a: c.o a: d.o the make command concludes that a depends on b.o, c.o, and d.o; that is, the preceding dependency statements are equivalent to a: b.o c.o d.o The make command treats dependency statements that have two colons differently, so that a description file that contains a:: b.o a:: c.o a:: d.o contains three separate dependency statements. If you use the single-colon rule, the target is updated when either of these conditions is true: ⊕ Any dependent is newer than the target. ⊕ The target does not exist. If you use the double-colon rule, the target is updated when any of these conditions is true: ⊕ Any dependent is newer than the target. 8 January 1992
make(1) make(1)⊕ The target does not exist. ⊕ The target does not have a dependency list. Double-colon dependency statements are useful for situations where a single target name is desired, but depending 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 directory, one or both target statements could be executed depending on whether the target is older than the dependents. If the target is missing, the target is considered to be older than the dependents. Double-colon dependency statements are also useful for situations in which a target has the same name as a subdirectory 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, 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 a 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. The make command 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 dependency statement has no dependency list, make processes January 1992 9
make(1) make(1)the commands that update the target even if the target already exists. The caveat is, however, that make always recompiles mail.c even when the executable mail file is newer than mail.c. A better solution to this problem is described under ``Attributes,'' later in the ``Description'' section. As mentioned earlier, you can replace a built-in rule by providing a new rule of the same name in the description file. You can also disable a built-in rule, as shown by the following example: .c.a:; The make command 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 default 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 just shown, or until make terminates. Built-in Targets The targets described in this section are actually built-in rules that you can enable by including them in a 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 beginning, 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 option, which is to cause make to ignore nonzero return codes from commands. 10 January 1992
make(1) make(1).MAKESTOP [ exit-code ]: If present, .MAKESTOP: causes make to exit. .MAKESTOP: is useful in a multilevel directory and description file hierarchy for quickly bypassing a make command in a particular directory or directories. The exit-code argument is optional. If you do not specify a value, the exit code defaults to 0. If no exit code is specified or if the specified exit code is zero, make exits silently. If a nonzero exit code is specified, make prints a warning message. .PRECIOUS: The default behavior of make is to remove a target and its dependents when a quit or interrupt signal is received while make is 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 potentially incomplete files helps ensure that the proper files are regenerated each time. You can avoid removal by making specific files dependent on .PRECIOUS:. See ``Error Handling,'' later in the ``Description'' section, for further details. .SILENT: If present, .SILENT: has the same effect as the -s command 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 in this section. The 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 the first simply requests that the string NAME be echoed, while the second, because of the prepended dollar sign ($), requests that the contents of NAME be echoed. Such a request is called ``expansion.'' January 1992 11
make(1) make(1)Expansion is handled differently by make. The example description file NAME=joe all: echo NAME echo $NAME produces the following result NAME AME This result is produced because make requires that macro names that are longer than one character be enclosed in parentheses or braces for expansion to occur. In this case, make sees the $ and attempts to expand a variable named N. No such variable is set, so nothing is echoed and the echo command completes by echoing AME. The following description file produces 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 makes all the variables found there available for modification 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 option causes environment variables to override macro definitions of the same name in a description file. The formal definition of a macro is macro-name = string2 By convention, macro names are uppercase. The macro-name argument is an alphanumeric string that cannot contain a colon (:) or a semicolon (;). The equal sign (=) can be 12 January 1992
make(1) make(1)surrounded by spaces or tabs. The string2 argument is defined as all characters up to a comment character or an unescaped newline. The make command provides several built-in macros. Here is a description of each macro. MAKECDIR A read-only macro that expands into the full pathname of the current directory. MAKEFLAGS If the MAKEFLAGS macro is not present in the environment, make creates and assigns to it the options with which make was invoked. MAKEFLAGS is processed by make as containing any legal input option (except -f, -p, -P, -r, and -u). Thus, MAKEFLAGS always contains the current input options. This macro proves very useful for ``super-makes.'' In fact, as noted earlier, when the -n option is used, the command $(MAKE) is executed anyway; hence, you can perform a make -n operation recursively on a whole software system to see what would have been executed. This is because the -n operation 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 the MAKELEVEL macro is not present in the environment, make creates it, assigns an initial value of zero, and exports it. If it is 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 multilevel make hierarchy. This macro is read-only and cannot be modified by the description file. MAKEBDIR If the MAKEDIR command is not present in the environment, make creates it, and assigns to it the absolute pathname of the current directory. If it is already present in the environment, the value of MAKEBDIR is not changed. MAKEBDIR provides a way for each subordindate invocation of make to obtain the pathname of the top-level make command. 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 January 1992 13
make(1) make(1)$ 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 the 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. The make command searches the directories specified by the VPATH variable for any dependencies that are not in the current directory. Consider the following example. VPATH=../common:../incl main: main.o func1.o func2.o cc -o $@ $> In this example, $@ (described later in this section) expands to the target name and $> (described later in this section) expands to the list of dependencies on the current target. If main.c, func1.c, or func2.c is not present in the current directory, make uses its built-in rules to search for SCCS versions of the files in the current directory. (See ``SCCS File Handling,'' later in the ``Description'' section.) If SCCS versions of the files are not found, make searches the pathnames specified by VPATH. The following built-in macros define values for common software generation programs or options to those programs. Description files can replace or supplement the 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 argument to the assembler. 14 January 1992
make(1) make(1)CC This macro is defined as cc. CFLAGS This macro is defined as -O and is provided as an argument 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 argument to the Fortran Compiler. FORTRAN This macro is defined as fortran. FORTRANFLAGS This macro is defined as null and is provided as an argument 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 argument to get. LD This macro is defined as ld. LDFLAGS This macro is defined as null and is provided as an argument to ld. LEX This macro is defined as lex. LFLAGS This macro is defined as null and is provided as an argument 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 January 1992 15
make(1) make(1)argument to pc. PC This macro is defined as pc. PCFLAGS This macro is defined as null and is provided as an argument 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 argument to yacc. The following six built-in macros have special expansion capabilities that are useful for writing shell commands. * The * macro stands for the filename 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 (that is, the ``manufactured'' dependent filename). Thus, in the .c.o rule, the < macro would evaluate to the .c file. Here is an example for making optimized .o files from .c files: .c.o: cc -c -O $*.c Here is another example: .c.o: cc -c -O $< ? 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 must be rebuilt. % The % macro is evaluated only when the target is an archive library member of the form lib(file.o). In this case, @ evaluates to lib and % evaluates to the 16 January 1992
make(1) make(1)library member, file.o. > The > macro is expanded to list all of the dependencies on the current rule. These six macros can have alternative forms. When an uppercase D or F is appended to any of the six 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. The following description file demonstrates the use of the ? and > macros in their standard and alternative 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 pgm, the following data 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 here: $(macro-name [: subst1 =[ subst2]]) The contents of a macro are replaced by string2, which is delimited by blanks, tabs, newline characters, or the beginning of a line. A substitute sequence can replace only the trailing characters of subst1. For example, SAMPLE=/a/b/file.test all: @echo "1 $(SAMPLE:file=FILE)" January 1992 17
make(1) make(1)@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 this example, only the second and fourth commands are successful. The other commands 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 This example uses the @ macro (expand to the full target name of the current target) and the ? macro (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 by 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 substitutions 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) The macro name can be set or unset and with or without an assigned value. The test-operator argument can be one of the following values: L The macro is expanded to the length of its 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. 18 January 1992
make(1) make(1)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 here: $(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 macro is the opposite of the V test operator and is used in the same way as the V test operator. For example, assume that you want 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 ignored when make reads the description file, and the line will be processed just as if the description file contained the following code: 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 expanded during the parsing of the command line. This means that the order of macros that have test operators is significant, 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. You can delay the expansion of macros that have test operators by prefixing more $ characters, just as you can with normal macros. In the example preceding, notice that $(CLNFILES:V) does not appear in front of each line. This is because a single command line was used, and that command line extended over two lines, with the newline escaped by the backslash (\) character. If there had been multiple command lines, a $(CLNFILES:V) macro would have been required at the January 1992 19
make(1) make(1)beginning of each line. Global Macros This version of make provides special handling of user- defined macros that begin with G_. Such macros are automatically 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 nonexistent or null-valued macros. The default value is specified as follows: $(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 restricted to a single word, so the following example would not have the intended result: $(XYZ::This is the default) Instead, XYZ would bd expanded to This. But the following example would 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. Here is an example: cc -o $@ $(>:=*.o) Each word in the expanded > macro is tested (shell-style) against the asterisk (*) pattern and compiled when there is a match. Attributes This version of make understands attributes, which can be placed before or after the dependents in a dependency list as shown here: target: [attributes] [dependents] [attributes] You can use any of the following attributes: .FAKE If the target exists and has no dependents, the normal 20 January 1992
make(1) make(1)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 as 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 attribute is used with the .FAKE attribute to prevent the associated dependency statement from being invoked unless the dependents have been updated with a newer time. .IDEBUGn If present, .IDEBUGn tells make not to display debugging information about this target at the desired debugging level. The variable n is set to a debugging level in the range of 0 to 9. For example, to prevent this target from showing up in your debugging sections at levels 0 and 1, you would specify .IDEBUG0 and .IDEBUG1. .IGNORE This attribute causes errors from any command of the target to be ignored. .MAIN The normal behavior of make when invoked without a target name on the command line is to search the description 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 dependency statement as if it were the first dependency statement in the description file. .NOMESS If present, .NOMESS causes make not to echo commands or issue any warning or error messages from commands. This attribute is useful in Pre and Post files if you do not want to see messages from these files. .PRE This attribute informs make that the associated target is to be made before any others, including .MAIN. You can use this attribute to place initialization 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 January 1992 21
make(1) make(1)This attribute informs make that the associated target is to be processed after all others. You can use this attribute to place cleanup commands. .PRECIOUS With this attribute, the document is considered ``precious.'' .KEEPTIME This attribute causes make to maintain the target's original modification time, even after the target has been regenerated. .OLDTIME This attribute causes make to ignore the target's modification time and apply a modification time of 0 for the purpose of determining if the target should be updated. After the target is regenerated, make sets the correct modification time. .SILENT With this attribute, the commands of this target are not echoed before execution. .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, not in the order dictated by the attributes. Attributes in 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 library that contains file.o. (Assuming that the LIB macro has been previously defined.) The expression $(LIB)(file1.o file2.o) is not legal. The built-in rules pertaining to archive libraries have the form .suffix.a where suffix is the suffix from which the archive member is to be made. An unfortunate by-product of the current implementation requires suffix to be different from the suffix of the archive member. Thus, you cannot have lib(file.o) depend upon file.o explicitly. 22 January 1992
make(1) make(1)Here is an example of the most common use of the archive interface. This example assumes that 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 in this example is built into make and need not actually be specified. Here is a more interesting, but more limited, example of an archive library maintenance construction: lib: lib(file1.o) lib(file2.o) lib(file3.o) $(CC) -c $(CFLAGS) $(?:.o=.c) ar rv 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-file names (inside lib) whose C source files are out-of-date. The substitution mode translates the .o to .c. (Unfortunately, you cannot as yet transform to .c~; however, this capability 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 construction speeds up archive library maintenance considerably. This type of construction becomes very cumbersome if the archive library contains a combination of assembly-language programs and C programs. MakeFile Preprocessing and Postprocessing If, by employing 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 option is specified, make will read /usr/lib/x.mkPre and /usr/lib/x.mkPost, if present. The preprocessing and postprocessing files are description files that can be used to store global environmental settings and rules for events that you want to occur prior to and after processing of a description file. January 1992 23
make(1) make(1)If the macro G_SGS_ROOT is present in the environment, make considers this macro to be the root for finding the preprocessing and postprocessing files. For example, if G_SGS_ROOT is set to newroot, make will look for the preprocessing and postprocessing files in the directory /newroot/usr/lib. SCCS File Handling As described in ``Description Files'' earlier in the ``Description'' section, make can checkout 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 subdirectory 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 option to make. The built-in rules for dependents can checkout only a file for which there is an SCCS version in the current directory; the built-in rules cannot checkout an SCCS version of a file located in a subdirectory named SCCS. If the -g option is used, however, and the file does not exist in the current directory, make will first use its built-in rules to check-out the file in the current directory. If this attempt fails because the SCCS version does not exist, the -g option causes make to search the current directory again and then search 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 option was specified. Searching the current directory makes the -g option especially useful with the -r option. The -r option turns off the built-in rules; thus, when -r is used with the -g option, the current directory is searched just once. If a VPATH variable is present and set, make uses the built-in rules to search the specified directories for SCCS versions of the file. If the -g 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 process include files. (See ``Include Files'' earlier in the ``Description'' section.) If an 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 option, however, make will check out an include file if it is present in an SCCS version in the current directory or in a subdirectory named SCCS. 24 January 1992
make(1) make(1)In no case does make check out a copy of a description file, an include file, or a dependent file if the file already exists. If a file is checked out by means of the built-in rules, make does not remove the checked-out copy. If a file is checked out by the action of the -g option, the checked-out copy is automatically removed when no longer needed. Dynamic Include File Dependency Generation (DIFDG) The make command can examine selected source files for #include directives. These include files are added to the target's dependency list. This feature, called DIFDG, relieves you from having to set up and create the include- file dependency list. The only disadvantage to having make create the dependency list is that some include files may be placed on the target's dependency list that would normally be left out during the compile because of an #ifdef statement. However, this behavior does not cause any problems; the target is still updated properly. The make utility does not add an include file to the target's dependency list unless that include file really exists, so no damage can result. You enable DIFDG by defining the _MAKE_DIFDG_SUFFIXES variable with a list of source-file suffixes to be searched, as in this example, or by specifying the -G (generate) option to make: _MAKE_DIFDG_SUFFIXES= .c .s .f .p .l The _MAKE_DIFDG_SUFFIXES variable must contain at least one suffix to enable DIFDG. An empty variable here does not have added meaning. The suffixes .o, .h, and .a are ignored. You can specify the list of directories to search for these include files by using the _MAKE_DIFDG_INCDIRS variable. The order is important because make searches each directory for include files until the files are found. Like cpp(1), make looks for include files of the form header.h first in the same directory as the source file (not always the current directory), then in the directories listed in the _MAKE_DIFDG_SUFFIXES variable. If an include file has the form <header.h>, the only directories searched are those listed in the variable. If this variable is defined but not assigned a value, the only directory that will be searched is the source-file directory. This means that <header.h> forms will always fail because there will not be a directory to search. If this variable is not defined, make uses the default /usr/include directory. January 1992 25
make(1) make(1)You can add a prefix to each include file dependent whose full pathname starts with /usr/include, by using the _MAKE_DIFDG_PREFIX variable. Use this variable only when you have specified the -M (map) option to request that the include-file dependencies be written. There is no default. Here is an example: _MAKE_DIFDG_PREFIX= $$(SGS_INCDIR) You can also use the c preprocessor, cpp, to create include-file dependency files. This method is much slower than that used by make. The last variable for DIFDG, _MAKE_DIFDG_CPPFLAGS, is defined with the flags to be passed to cpp. Merely defining this variable enables the cpp method of finding include files. If you do not define this variable, make uses the faster method. When you assign a value to this variable, keep in mind that only words that start with a hyphen are passed to cpp as in this example. (It is assumed that DEFINES is a variable that contains -D style macros.) _MAKE_DIFDG_CPPFLAGS= -Y $(DEFINES) If the _MAKE_DIFDG_FILE variable is set and non-null, and DIFDG is enabled, the DIFDG include-file dependencies will be written to the variable it when make exits. If the -G option is used, the defaults are as follows: _MAKE_DIFDG_SUFFIXES= .c .l .y _MAKE_DIFDG_INCDIRS= /usr/include _MAKE_DIFDG_CPPFLAGS= _MAKE_DIFDG_PREFIX= Error Handling Shell commands that return a nonzero status normally terminate make. You can modify this behavior in a number of ways: -i If present on the command line, this 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,'' earlier in the ``Description'' section. -k If present on the command line, this option causes make to abandon work on the current target if a shell command returns a nonzero status. The make command will continue to work on other targets in the 26 January 1992
make(1) make(1)description file that do not depend on the target for which the error was received. - If a hyphen is prepended to any shell command, make will not terminate on an error that might occur as a result of executing the command, but will continue processing the description file. The - can be combined with the previously described @ symbol, described in ``Section Name'' earlier in the ``Description'' section, which suppresses the printing 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 commands standard error messages are still printed. As mentioned earlier, make removes a target and its dependents when a quit or interrupt signal is received. The following conditions apply: ⊕ 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. ⊕ The target must have existed before processing of the dependency statement began. ⊕ The target must not be a dependent of the built-in target .PRECIOUS:. ⊕ The make must not have been invoked with the -n option. ⊕ The make command must not have been invoked with the -t option. An example of the standard termination message generated because of a nonzero status code is shown here. 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. LIMITATIONS The syntax (lib(file1.o file2.o file3.o) is illegal. You cannot build lib(file.o) from file.o. January 1992 27
make(1) make(1)The macro $(a:.o=.c~) does not work. FILES $HOME/[Mm]akecomm File /bin/make Executable file [Mm]akecomm File s.[Mm]ake[Ff]ile File SCCS/s.[Mm]ake[Ff]ile File SEE ALSO cd(1), csh(1), ksh(1), lex(1), sh(1), touch(1), yacc(1) printf(3S), sccsfile(4) in A/UX Programmer's Reference ``make Reference'' in A/UX Programming Languages and Tools, Volume 2 28 January 1992