diff options
Diffstat (limited to 'dmake/man')
-rw-r--r-- | dmake/man/dmake.nc | 3644 | ||||
-rw-r--r-- | dmake/man/dmake.tf | 3480 | ||||
-rw-r--r-- | dmake/man/readme | 12 |
3 files changed, 7136 insertions, 0 deletions
diff --git a/dmake/man/dmake.nc b/dmake/man/dmake.nc new file mode 100644 index 000000000000..9961119ddf6b --- /dev/null +++ b/dmake/man/dmake.nc @@ -0,0 +1,3644 @@ + + + +DMAKE(1) DMAKE(1) + + +NAME + dmake - maintain program groups, or interdependent files + +SYNOPSIS + dmake [-P#] [-{f|C|K} file] [-{w|W} target ...] + [macro[[!][*][+][:]]=value ...] [-ABcdeEghiknpqrsStTuVxX] + [-v[cdfimrtw]] [-m[trae]] [target ...] + +DESCRIPTION + dmake is a re-implementation of the UNIX Make utility with significant + enhancements. dmake executes commands found in an external file called + a makefile to update one or more target names. Each target may depend + on zero or more prerequisite targets. If any of the target's prerequi- + sites is newer than the target or if the target itself does not exist, + then dmake will attempt to make the target. + + If no -f command line option is present then dmake searches for an + existing makefile from the list of prerequisites specified for the spe- + cial target .MAKEFILES (see the STARTUP section for more details). If + "-" is the name of the file specified to the -f flag then dmake uses + standard input as the source of the makefile text. + + Any macro definitions (arguments with embedded "=" signs) that appear + on the command line are processed first and supercede definitions for + macros of the same name found within the makefile. In general it is + impossible for definitions found inside the makefile to redefine a + macro defined on the command line, see the MACROS section for excep- + tions. + + If no target names are specified on the command line, then dmake uses + the first non-special target found in the makefile as the default tar- + get. See the SPECIAL TARGETS section for the list of special targets + and their function. Makefiles written for most previous versions of + Make will be handled correctly by dmake. Known differences between + dmake and other versions of make are discussed in the COMPATIBILITY + section found at the end of this document. dmake returns 0 if no + errors were detected and a non-zero result if an error occurred. + +OPTIONS + -A Enable AUGMAKE special inference rule transformations (see the + "PERCENT(%) RULES" and "AUGMAKE META RULES" sections), these are + set to off by default. + + -B Enable the use of spaces instead of <tabs> to begin recipe + lines. This flag equivalent to the .NOTABS special macro and is + further described below. + + -c Use non-standard comment stripping. If you specify -c then + dmake will treat any # character as a start of comment character + wherever it may appear unless it is escaped by a \. + + -C [+]file + This option writes to file a copy of standard output and stan- + dard error from any child processes and from the dmake process + + + +Dmake Version 4.12 2008-02-26 1 + + + + + +DMAKE(1) DMAKE(1) + + + itself. If you specify a + prior to the file name then the text + is appended to the previous contents of file. This option is + active in the MSDOS implementation only and is ignored by non- + MSDOS versions of dmake. + + -d Disable the use of the directory cache. Normally dmake caches + directories as it checks file timestamps. Giving this flag is + equivalent to the .DIRCACHE attribute or macro being set to no. + + -E Read the environment and define all strings of the form + 'ENV-VAR=evalue' defined within as macros whose name is ENV-VAR, + and whose value is 'evalue'. The environment is processed prior + to processing the user specified makefile thereby allowing defi- + nitions in the makefile to override definitions in the environ- + ment. + + -e Same as -E, except that the environment is processed after the + user specified makefile has been processed (thus definitions in + the environment override definitions in the makefile). The -e + and -E options are mutually exclusive. If both are given the + latter takes effect. + + -f file + Use file as the source for the makefile text. Only one -f + option is allowed. + + -g Globally disable group recipe parsing, equivalent to the + .IGNOREGROUP attribute or macro being set to yes at the start of + the makefile. + + -h Print the command summary for dmake. + + -i Tells dmake to ignore errors, and continue making other targets. + This is equivalent to the .IGNORE attribute or macro. + + -K file + Turns on .KEEP_STATE state tracking and tells dmake to use file + as the state file. + + -k Causes dmake to ignore errors caused by command execution and to + make all targets not depending on targets that could not be + made. Ordinarily dmake stops after a command returns a non-zero + status, specifying -k causes dmake to ignore the error and con- + tinue to make as much as possible. + + -m[trae] + Measure timing information. Print the time when targets and/or + recipes are started and finished to stdout. The following format + is used: + + {s|e} {target|recipe} time maketarget + + s or e stands for started or ended, target or recipe denotes if + this line refers to the whole target or a recipe. time is + + + +Dmake Version 4.12 2008-02-26 2 + + + + + +DMAKE(1) DMAKE(1) + + + displayed in Unix time format, i.e. the number of seconds since + an epoch. (Since 1970-01-01T00:00:00Z). maketarget obviously + represents the target the timing information is given for. The + optional flags [trae] can be used to change the information that + is displayed. If no optional flags are given only the t flag is + assumed to be selected, ie. -mt. The optional flags stand for: + + t Display the start and end time of each target. + + r Display the start and end time of each recipe. + + a Display the target as an absolute path, i.e. prepend the + current working directory. + + e Also display the start and end time of the $(shell com- + mand) function (aka. shell escape) macros. + + -n Causes dmake to print out what it would have executed, but does + not actually execute the commands. A special check is made for + the string "$(MAKE)" inside a recipe line, if it is found, the + line is expanded and invoked, thereby enabling recursive makes + to give a full description of all that they will do. This check + is disabled inside group recipes. + + -p Print out a version of the digested makefile in human readable + form. (useful for debugging, but cannot be re-read by dmake) + + -P# On systems that support multi-processing cause dmake to use # + concurrent child processes to make targets. See the "MULTI PRO- + CESSING" section for more information. + + -q Check and see if the target is up to date. Exits with code 0 if + up to date, 1 otherwise. + + -r Tells dmake not to read the initial startup makefile, see + STARTUP section for more details. + + -s Tells dmake to do all its work silently and not echo the com- + mands it is executing to stdout (also suppresses warnings). + This is equivalent to the .SILENT attribute or macro. + + -S Force sequential execution of recipes on architectures which + support concurrent makes. For backward compatibility with old + makefiles that have nasty side-effect prerequisite dependencies. + (Implies -P1) + + -t Causes dmake to touch the targets and bring them up to date + without executing any commands. Note that targets will not be + created if they do not already exist. + + -T Tells dmake to not perform transitive closure on the inference + graph. + + -u Force an unconditional update. (ie. do everything that would be + done if everything that a target depended on was out of date) + + + +Dmake Version 4.12 2008-02-26 3 + + + + + +DMAKE(1) DMAKE(1) + + + -v[cdfimrtw] + Verbose flag, when making targets print to stdout what we are + going to make and what we think its time stamp is. The optional + flags [cdfimrtw] can be used to restrict the information that is + displayed. In the absence of any optional flags all are assumed + to be given (ie. -v is equivalent to -vcdfimrtw). The meanings + of the optional flags are: + + c Notify of directory cache operations only. + + d Notify of change directory operations only. + + f Notify of file I/O operations only. + + i Notify of inference algorithm operation only. + + m Notify of target update operations only. + + r Force output of recipe lines, warnings and executed com- + mands. This switch is usefull when debugging makefiles + that disable the output using the @ or @@ property for + recipe lines or the .SILENT target/attribute. It also + overrides the -s flag. + + t Keep any temporary files created; normally they are auto- + matically deleted. + + w Notify of non-essential warnings (these are historical). + + -V Print the version of dmake, and values of builtin macros. + + -W target + Run dmake pretending that target is out of date. + + -w target + What if? Show what would be made if target were out of date. + + -x Upon processing the user makefile export all non-internally + defined macros to the user's environment. This option together + with the -e option allows SYSV AUGMAKE recursive makes to func- + tion as expected. + + -X Inhibit the execution of #! lines found at the beginning of a + makefile. The use of this flag prevents non-termination of + recursive make invocations. + +INDEX + Here is a list of the sections that follow and a short description of + each. Perhaps you won't have to read the entire man page to find what + you need. + + STARTUP Describes dmake initialization. + + SYNTAX Describes the syntax of makefile expressions. + + + + +Dmake Version 4.12 2008-02-26 4 + + + + + +DMAKE(1) DMAKE(1) + + + ATTRIBUTES Describes the notion of attributes and how they are + used when making targets. + + MACROS Defining and expanding macros. + + RULES AND TARGETS How to define targets and their prerequisites. + + RECIPES How to tell dmake how to make a target. + + BUILTIN COMMANDS Internal dmake commands. + + TEXT DIVERSIONS How to use text diversions in recipes and macro + expansions. + + VIRTUAL TARGETS Targets that only enforce dependencies, but which + can not create a target file. + + SPECIAL TARGETS Some targets are special. + + SPECIAL MACROS Macros used by dmake to alter the processing of the + makefile, and those defined by dmake for the user. + + CONTROL MACROS Itemized list of special control macros. + + RUNTIME MACROS Discussion of special run-time macros such as $@ and + $<. + + FUNCTION MACROS Description of functional macros. + + CONDITIONAL MACROS Target specific conditional macros. + + DYNAMIC PREREQUISITES + Processing of prerequisites which contain macro + expansions in their name. + + BINDING TARGETS The rules that dmake uses to bind a target to an + existing file in the file system. + + PERCENT(%) RULES Specification of recipes to be used by the inference + algorithm. + + MAKING INFERENCES The rules that dmake uses when inferring how to make + a target which has no explicit recipe. This and the + previous section are really a single section in the + text. + + AUGMAKE META RULES A subclass of the PERCENT(%) RULES. + + MAKING TARGETS How dmake makes targets other than libraries. + + MAKING LIBRARIES How dmake makes libraries. + + KEEP STATE A discussion of how .KEEP_STATE works. + + MULTI PROCESSING Discussion of dmake's parallel make facilities for + architectures that support them. + + + +Dmake Version 4.12 2008-02-26 5 + + + + + +DMAKE(1) DMAKE(1) + + + CONDITIONALS Conditional expressions which control the processing + of the makefile. + + EXAMPLES Some hopefully useful examples. + + COMPATIBILITY How dmake compares with previous versions of make. + + LIMITS Limitations of dmake. + + PORTABILITY Comments on writing portable makefiles. + + FILES Files used by dmake. + + SEE ALSO Other related programs, and man pages. + + AUTHOR The guy responsible for this thing. + + BUGS Hope not. + +STARTUP + When dmake begins execution it first processes the command line and + then processes an initial startup-makefile. This is followed by an + attempt to locate and process a user supplied makefile. The startup + file defines the default values of all required control macros and the + set of default rules for making targets and inferences. When searching + for the startup makefile, dmake searches the following locations, in + the order specified, until a startup file is located: + + + 1. The location given as the value of the macro MAKESTARTUP + defined on the command line. + + 2. The location given as the value of the environment vari- + able MAKESTARTUP defined in the current environment. + + 3. The location given as the value of the macro MAKESTARTUP + defined internally within dmake. In this version, the + internal definition of MAKESTARTUP is "$(DMAKE- + ROOT)/startup.mk", so you can set the environment vari- + able DMAKEROOT to the location of your startup directory. + + If DMAKEROOT is not changed, for native Windows dmake + versions its value defaults to "$(ABSMAKECMD:d)startup" + (see definition of ABSMAKECMD for details). For unix + like versions build with the autotools build system it + defaults to the value of "${prefix}/share/startup" at + build time. The actual value, usually something like + /usr/local/share/startup can be checked with the -V com- + mand line switch. + + The above search is disabled by specifying the -r option on the command + line. An error is issued if a startup makefile cannot be found and the + -r option was not specified. A user may substitute a custom startup + file by defining the MAKESTARTUP environment variable or by redefining + the MAKESTARTUP macro on the command line. To determine where dmake + looks for the default startup file, check your environment or issue the + + + +Dmake Version 4.12 2008-02-26 6 + + + + + +DMAKE(1) DMAKE(1) + + + command "dmake -V". + + A similar search is performed to locate a default user makefile when no + -f command line option is specified. By default, the prerequisite list + of the special target .MAKEFILES specifies the names of possible make- + files and the search order that dmake should use to determine if one + exists. A typical definition for this target is: + + .MAKEFILES : makefile.mk Makefile makefile + + dmake will first look for makefile.mk and then the others. If a pre- + requisite cannot be found dmake will try to make it before going on to + the next prerequisite. For example, makefile.mk can be checked out of + an RCS file if the proper rules for doing so are defined in the startup + file. + + If the first line of the user makefile is of the form: + + #!command command_args + + then dmake will expand and run the command prior to reading any addi- + tional input. If the return code of the command is zero then dmake + will continue on to process the remainder of the user makefile, if the + return code is non-zero then dmake will exit. + + dmake builds the internal dependency graph as it parses a user speci- + fied makefile. The graph is rooted at the special target .ROOT. .ROOT + is the top level target that dmake builds when it starts to build tar- + gets. All user specified targets (those from the command line or taken + as defaults from the makefile) are made prerequisites of the special + target .TARGETS. dmake by default creates the relationship that .ROOT + depends on .TARGETS and as a result everything is made. This approach + allows the user to customize, within their makefile, the order and + which, target, is built first. For example the default makefiles come + with settings for .ROOT that specify: + + .ROOT .PHONY .NOSTATE .SEQUENTIAL : .INIT .TARGETS .DONE + + with .INIT and .DONE defined as: + + .INIT .DONE .PHONY:; + + which nicely emulates the behaviour of Sun's make extensions. The + building of .ROOT's prerequisites is always forced to be sequential. + However, this definition is trivially changed by supplying the defini- + tion: + + .ROOT : .TARGETS + + which skips the preamble and postamble phases of building .TARGETS. + + Please note that even though .INIT and .DONE are special exceptions, + see section SPECIAL TARGETS, the use of self defined targets starting + with `.' should be avoided as they would be handled as .<suffix> meta + targets. The target names _INIT and _DONE for example would work + equally well without the .<suffix> drawback. + + + +Dmake Version 4.12 2008-02-26 7 + + + + + +DMAKE(1) DMAKE(1) + + +SYNTAX + This section is a summary of the syntax of makefile statements. The + description is given in a style similar to BNF, where { } enclose items + that may appear zero or more times, and [ ] enclose items that are + optional. Alternative productions for a left hand side are indicated + by '->', and newlines are significant. All symbols in bold type are + text or names representing text supplied by the user. + + + + + Makefile -> { Statement } + + + Statement -> Macro-Definition + -> Conditional-Macro-Definition + -> Conditional + -> Rule-Definition + -> Attribute-Definition + + + Macro-Definition -> MACRO = LINE + -> MACRO [!]*= LINE + -> MACRO [!]:= LINE + -> MACRO [!]*:= LINE + -> MACRO [!]+= LINE + -> MACRO [!]+:= LINE + + + Conditional-Macro-Definition -> TARGET ?= Macro-Definition + + + Conditional -> .IF expression + Makefile + [ .ELIF expression + Makefile ] + [ .ELSE + Makefile ] + .END + + + expression -> LINE + -> STRING + -> expression == expression + -> expression != expression + -> expression <= expression + -> expression >= expression + -> ( expression ) + -> expression || expression + -> expression && expression + + + Rule-Definition -> target-definition + [ recipe ] + + target-definition -> targets [attrs] op { PREREQUISITE } [; rcp-line] + + + +Dmake Version 4.12 2008-02-26 8 + + + + + +DMAKE(1) DMAKE(1) + + + targets -> target { targets } + -> "target" { targets } + + + target -> special-target + -> TARGET + + + attrs -> attribute { attrs } + -> "attribute" { attrs } + + + op -> : { modifier } + + + modifier -> : + -> ^ + -> ! + -> - + -> | + + + recipe -> { TAB rcp-line } + -> [@[@]][%][-] [ + { LINE } + ] + + + rcp-line -> [@[@]][%][-][+] LINE + + + Attribute-Definition -> attrs : targets + + + attribute -> .EPILOG + -> .ERRREMOVE + -> .EXECUTE + -> .GROUP + -> .IGNORE + -> .IGNOREGROUP + -> .LIBRARY + -> .MKSARGS + -> .NOINFER + -> .NOSTATE + -> .PHONY + -> .PRECIOUS + -> .PROLOG + -> .SETDIR=path + -> .SILENT + -> .SEQUENTIAL + -> .SWAP + -> .USESHELL + -> .SYMBOL + -> .UPDATEALL + -> .WINPATH + + + + +Dmake Version 4.12 2008-02-26 9 + + + + + +DMAKE(1) DMAKE(1) + + + special-target -> .ERROR + -> .EXIT + -> .EXPORT + -> .GROUPEPILOG + -> .GROUPPROLOG + -> .IMPORT + -> .INCLUDE + -> .INCLUDEDIRS + -> .MAKEFILES + -> .REMOVE + -> .ROOT + -> .SOURCE + -> .SOURCE.suffix + -> .SUFFIXES (deprecated) + -> .TARGETS + -> .INIT + -> .DONE + -> .suffix + -> .suffix1.suffix2 + + + Where, TAB represents a <tab> character, STRING represents an arbitrary + sequence of characters, and LINE represents a possibly empty sequence + of characters terminated by a non-escaped (not immediately preceded by + a backslash '\') new-line character. MACRO, PREREQUISITE, and TARGET + each represent a string of characters not including space or tab which + respectively form the name of a macro, prerequisite or target. The + name may itself be a macro expansion expression. A LINE can be contin- + ued over several physical lines by terminating it with a single back- + slash character. Comments are initiated by the pound # character and + extend to the end of line. All comment text is discarded, a '#' may be + placed into the makefile text by escaping it with '\' (ie. \# trans- + lates to # when it is parsed). An exception to this occurs when a # is + seen inside a recipe line that begins with a <tab> or is inside a group + recipe. If you specify the -c command line switch then this behavior + is disabled and dmake will treat all # characters as start of comment + indicators unless they are escaped by \. A set of continued lines may + be commented out by placing a single # at the start of the first line. + A continued line cannot span more than one makefile. + + white space is defined to be any combination of <space>, <tab>, and the + sequence \<nl> when \<nl> is used to terminate a LINE. Note the special + treatment of \<nl> in macro definion and recipe lines below. When pro- + cessing macro definition lines, any amount of white space is allowed on + either side of the macro operator and white space is stripped from both + before and after the macro value string. A \<nl> sequence in a macro + definition is deleted from the macro value before assigning this value. + During recipe expansion the sequence \<nl> is treated as white space + but is deleted from the final recipe string. You must escape the \<nl> + with another \ in order to get a \ at the end of a recipe or macro def- + inition line. + + When processing target definition lines, the recipe for a target must, + in general, follow the first definition of the target (See the RULES + AND TARGETS section for an exception), and the recipe may not span + across multiple makefiles. Any targets and prerequisites found on a + + + +Dmake Version 4.12 2008-02-26 10 + + + + + +DMAKE(1) DMAKE(1) + + + target definition line are taken to be white space separated tokens. + The rule operator (op in SYNTAX section) is also considered to be a + token but does not require white space to precede or follow it. Since + the rule operator begins with a `:', traditional versions of make do + not allow the `:' character to form a valid target name. dmake allows + `:' to be present in target/prerequisite names as long as the entire + target/prerequisite name is quoted. For example: + + a:fred : test + + would be parsed as TARGET = a, PREREQUISITES={fred, :, test}, which is + not what was intended. To fix this you must write: + + "a:fred" : test + + Which will be parsed as expected. Quoted target and prerequisite spec- + ifications may also contain white space thereby allowing the use of + complex function macro expressions.. See the EXAMPLES section for how + to apply " quoting to a list of targets. + +ATTRIBUTES + dmake defines several target attributes. Attributes may be assigned to + a single target, a group of targets, or to all targets in the makefile. + Attributes are used to modify dmake actions during target update. The + recognized attributes are: + + + .EPILOG Insert shell epilog code when executing a group recipe + associated with any target having this attribute set. + + .ERRREMOVE Always remove any target having this attribute if an error + is encountered while making them. Setting this attribute + overrides the .PRECIOUS attribute. + + .EXECUTE If the -n flag was given then execute the recipe associated + with any target having this attribute set. + + .FIRST Used in conjunction with .INCLUDE. Terminates the inclu- + sion with the first successfully included prerequisite. + + .GROUP Force execution of a target's recipe as a group recipe. + + .IGNORE Ignore an error when trying to make any target with this + attribute set. + + .IGNOREGROUP + Disable the special meaning of '[' to initiate a group + recipe. + + .LIBRARY Target is a library. + + .MKSARGS If running in an MSDOS environment then use MKS extended + argument passing conventions to pass arguments to commands. + Non-MSDOS environments ignore this attribute. + + .NOINFER Any target with this attribute set will not be subjected to + transitive closure if it is inferred as a prerequisite of a + + + +Dmake Version 4.12 2008-02-26 11 + + + + + +DMAKE(1) DMAKE(1) + + + target whose recipe and prerequisites are being inferred. + (i.e. the inference algorithm will not use any prerequisite + with this attribute set, as a target) If specified as + '.NOINFER:' (ie. with no prerequisites or targets) then the + effect is equivalent to specifying -T on the command line. + + .NOSTATE Any target with this attribute set will not have command + line flag information stored in the state file if + .KEEP_STATE has been enabled. + + .PHONY Any target with this attribute set will have its recipe + executed each time the target is made even if a file match- + ing the target name can be located. Any targets that have + a .PHONY attributed target as a prerequisite will be made + each time the .PHONY attributed prerequisite is made. + + .PRECIOUS Do not remove associated target under any circumstances. + Set by default for any targets whose corresponding files + exist in the file system prior to the execution of dmake. + + .PROLOG Insert shell prolog code when executing a group recipe + associated with any target having this attribute set. + + .SEQUENTIAL Force a sequential make of the associated target's prereq- + uisites. If set as a global attribute this implies setting + MAXPROCESS=1. + + .SETDIR Change current working directory to specified directory + when making the associated target. You must specify the + directory at the time the attribute is specified. To do + this simply give .SETDIR=path as the attribute. path is + expanded and the result is used as the value of the direc- + tory to change to. If path contains $$@ then the name of + the target to be built is used in computing the path to + change directory to. If path is surrounded by single + quotes then path is not expanded, and is used literally as + the directory name. If the path contains any `:' charac- + ters then the entire attribute string must be quoted using + ". If a target having this attribute set also has the + .IGNORE attribute set then if the change to the specified + directory fails it will be ignored, and no error message + will be issued. + + .SILENT Do not echo the recipe lines when making any target with + this attribute set, and do not issue any warnings. + + .SWAP Under MSDOS when making a target with this attribute set + swap the dmake executable to disk prior to executing the + recipe line. Also see the '%' recipe line flag defined in + the RECIPES section. + + .SYMBOL Target is a library member and is an entry point into a + module in the library. This attribute is used only when + searching a library for a target. Targets of the form + lib((entry)) have this attribute set automatically. + + .USESHELL Force each recipe line of a target to be executed using a + shell. Specifying this attribute is equivalent to + + + +Dmake Version 4.12 2008-02-26 12 + + + + + +DMAKE(1) DMAKE(1) + + + specifying the '+' character at the start of each line of a + non-group recipe. + + .UPDATEALL Indicates that all the targets listed in this rule are + updated by the execution of the accompanying recipe. A + common example is the production of the y.tab.c and y.tab.h + files by yacc when it is run on a grammar. Specifying + .UPDATEALL in such a rule prevents the running of yacc + twice, once for the y.tab.c file and once for the y.tab.h + file. .UPDATEALL targets that are specified in a single + rule are treated as a single target and all timestamps are + updated whenever any target in the set is made. As a side- + effect, dmake internally sorts such targets in ascending + alphabetical order and the value of $@ is always the first + target in the sorted set. + + .WINPATH Switch between default (POSIX) and Windows style path rep- + resentation. (This attribute is specific for cygwin dmake + executables and non-cygwin environments ignore this + attribute.) + + Under Cygwin it can be useful to generate Windows style + paths (with regular slashes) instead of the default cygwin + style (POSIX) paths for dmake's dynamic macros. The + affected macros are $@, $*, $>, $?, $<, $&, $^ and + $(MAKEDIR), $(PWD), $(TMD), $(TMPFILE) and the $(mktmp ...) + function macro. This feature can be used to create DOS + style path parameters for native W32 programs from dynamic + macros. + + Note that the Windows style paths use regular slashes ('/') + instead of the usual Windows backslash ('\') as directory + separator to avoid quoting problems (after all it is still + a cygwin dmake!) and cygwin, as well as native Windows, + programs should have no problems using this (c:/foo/bar) + path representation. + + Example: Assuming the current target to be /tmp/mytarget + the $@ macro without .WINPATH active expands to: + + /tmp/mytarget + + With .WINPATH set it expands to: + + C:/cygwin/tmp/mytarget + + All attributes are user setable and except for .UPDATEALL and .MKSARGS + may be used in one of two forms. The .MKSARGS attribute is restricted + to use as a global attribute, and the use of the .UPDATEALL attribute + is restricted to rules of the second form only. + + ATTRIBUTE_LIST : targets + + assigns the attributes specified by ATTRIBUTE_LIST to each target in + targets or + + targets ATTRIBUTE_LIST : ... + + + + +Dmake Version 4.12 2008-02-26 13 + + + + + +DMAKE(1) DMAKE(1) + + + assigns the attributes specified by ATTRIBUTE_LIST to each target in + targets. In the first form if targets is empty (ie. a NULL list), then + the list of attributes will apply to all targets in the makefile (this + is equivalent to the common Make construct of ".IGNORE :" but has been + modified to the notion of an attribute instead of a special target). + Not all of the attributes have global meaning. In particular, + .LIBRARY, .NOSTATE, .PHONY, .SETDIR, .SYMBOL and .UPDATEALL have no + assigned global meaning. + + Any attribute may be used with any target, even with the special tar- + gets. Some combinations are useless (e.g. .INCLUDE .PRECIOUS: ... ), + while others are useful (e.g. .INCLUDE .IGNORE : "file.mk" will not + complain if file.mk cannot be found using the include file search + rules, see the section on SPECIAL TARGETS for a description of + .INCLUDE). If a specified attribute will not be used with the special + target a warning is issued and the attribute is ignored. + +MACROS + dmake supports six forms of macro assignment. + + + MACRO = LINE This is the most common and familiar form of macro + assignment. It assigns LINE literally as the value of + MACRO. Future expansions of MACRO recursively expand + its value. + + MACRO *= LINE This form behaves exactly as the simple '=' form with + the exception that if MACRO already has a value then + the assignment is not performed. + + MACRO := LINE This form differs from the simple '=' form in that it + expands LINE prior to assigning it as the value of + MACRO. Future expansions of MACRO do not recursively + expand its value. + + MACRO *:= LINE This form behaves exactly as the ':=' form with the + exception that if MACRO already has a value then the + assignment and expansion are not performed. + + MACRO += LINE This form of macro assignment allows macro values to + grow. It takes the literal value of LINE and appends + it to the previous value of MACRO separating the two by + a single space. Future expansions of MACRO recursively + expand its value. + + MACRO +:= LINE This form is similar to the '+=' form except that the + value of LINE is expanded prior to being added to the + value of MACRO. + + Macro expressions specified on the command line allow the macro value + to be redefined within the makefile only if the macro is defined using + the '+=' and '+:=' operators. Other operators will define a macro that + cannot be further modified. + + Each of the preceeding macro assignment operators may be prefixed by ! + to indicate that the assignment should be forced and that no warnings + should be issued. Thus, specifying ! has the effect of silently forc- + ing the specified macro assignment. + + + +Dmake Version 4.12 2008-02-26 14 + + + + + +DMAKE(1) DMAKE(1) + + + When dmake defines a non-environment macro it strips leading and trail- + ing white space from the macro value. Macros imported from the envi- + ronment via either the .IMPORT special target (see the SPECIAL TARGETS + section), or the -e, or -E flags are an exception to this rule. Their + values are always taken literally and white space is never stripped. + In addition, named macros defined using the .IMPORT special target do + not have their values expanded when they are used within a makefile. + In contrast, environment macros that are imported due to the specifica- + tion of the -e or -E flags are subject to expansion when used. + + To specify a macro expansion enclose the name in () or {} and precede + it with a dollar sign $. Thus $(TEST) represents an expansion of the + macro variable named TEST. If TEST is defined then $(TEST) is replaced + by its expanded value. If TEST is not defined then $(TEST) expands to + the NULL string (this is equivalent to defining a macro as 'TEST=' ). + A short form may be used for single character named macros. In this + case the parentheses are optional, and $(I) is equivalent to $I. Macro + expansion is recursive, hence, if the value string contains an expres- + sion representing a macro expansion, the expansion is performed. Cir- + cular macro expansions are detected and cause an error to be issued. + + When defining a macro the given macro name is first expanded before + being used to define the macro. Thus it is possible to define macros + whose names depend on values of other macros. For example, suppose CWD + is defined as + + CWD = $(PWD:b) + + then the value of $(CWD) is the name of the current directory. This + can be used to define macros specific to this directory, for example: + + _$(CWD).prt = list of files to print... + + The actual name of the defined macro is a function of the current + directory. A construct such as this is useful when processing a hier- + archy of directories using .SETDIR attributed targets and a collection + of small distributed makefile stubs. + + Macro variables may be defined within the makefile, on the command + line, or imported from the environment. + + dmake supports several non-standard macro expansions: The first is of + the form: + + $(macro_name:modifier_list:modifier_list:...) + + where modifier_list may be a combination of: + + b or B - file (not including suffix) portion of path names + d or D - directory portion of all path names + e or E - suffix portion of path names + f or F - file (including suffix) portion of path names + i or I - inferred names of targets + n or N - normalized path names + l or L - macro value in lower case + u or U - macro value in upper case + 1 - return the first white space separated token from value + + + + +Dmake Version 4.12 2008-02-26 15 + + + + + +DMAKE(1) DMAKE(1) + + + or a single one of: + + m or M - map escape codes found in macro to their ASCII value + s or S - simple pattern substitution + t or T - tokenization. + ^ - prepend a prefix to each token + + - append a suffix to each token + + Thus if we have the example: + test = d1/d2/d3/a.out f.out d1/k.out + The following macro expansions produce the values on the right of '->' + after expansion. + + $(test:d) -> d1/d2/d3/ d1/ + $(test:b) -> a f k + $(test:f) -> a.out f.out k.out + ${test:db} -> d1/d2/d3/a f d1/k + ${test:s/out/in/:f} -> a.in f.in k.in + $(test:f:t"+") -> a.out+f.out+k.out + $(test:e) -> .out .out .out + $(test:u) -> D1/D2/D3/A.OUT F.OUT D1/K.OUT + $(test:1) -> d1/d2/d3/a.out + + For this macro + test = d1/d2/../a.out "d1/file name.ext" + the following results are returned: + + $(test:n) -> d1/a.out "d1/file name.ext" + + If a token ends in a string composed from the value of the macro + DIRBRKSTR (ie. ends in a directory separator string, e.g. '/' in UNIX) + and you use the :d modifier then the expansion returns the directory + name less the final directory separator string. Thus successive pairs + of :d modifiers each remove a level of directory in the token string. + + The infered names of targets :i modifier returnes the actual filename + associated to the target, see BINDING TARGETS. If the value is not a + target or prerequisite the value is returned unchanged. For the follow- + ing example: + test = aprog bprog + If aprog and bprog are targets or prerequisits and they are bound to + /tmp/aprog and bprog (see .SOURCE special target) the macro expansion + has the following effect: + + $(test:i) -> /tmp/aprog bprog + + The normalized path names :n modifier honors the setting of .WINPATH to + determine the output format of the result. + + The map escape codes modifier changes the following escape codes \a => + <bel>, \b => <backspace>, \f => <formfeed>, \n => <nl>, \r => <cr>, \t + => <tab>, \v => <vertical tab>, \" => ", and \xxx => <xxx> where xxx is + the octal representation of a character into the corresponding ASCII + value. + + The tokenization, prepend and append modifier may use the same escape + codes that are supported by the map escape codes modifier in the string + that is inserted, prepended or added by the respective macro modifier. + + + +Dmake Version 4.12 2008-02-26 16 + + + + + +DMAKE(1) DMAKE(1) + + + These modifiers may quote this string to include otherwise problematic + characters. E.g. spaces, colons and parentheses. + + The tokenization modifier takes all white space separated tokens from + the macro value and separates them by the separator string. Thus the + expansion: + + $(test:f:t"+\n") + produces: + a.out+ + f.out+ + k.out + + The prefix operator ^ takes all white space separated tokens from the + macro value and prepends string to each. + + $(test:f:^mydir/) + produces: + mydir/a.out mydir/f.out mydir/k.out + + The suffix operator + takes all white space separated tokens from the + macro value and appends string to each. + + $(test:b:+.c) + produces: + a.c f.c k.c + + The next non-standard form of macro expansion allows for recursive + macros. It is possible to specify a $(macro_name) or ${macro_name} + expansion where macro_name contains more $( ... ) or ${ ... } macro + expansions itself. + + For example $(CC$(_HOST)$(_COMPILER)) will first expand + CC$(_HOST)$(_COMPILER) to get a result and use that result as the name + of the macro to expand. This is useful for writing a makefile for more + than one target environment. As an example consider the following + hypothetical case. Suppose that _HOST and _COMPILER are imported from + the environment and are set to represent the host machine type and the + host compiler respectively. + + CFLAGS_VAX_CC = -c -O # _HOST == "_VAX", _COMPILER == "_CC" + CFLAGS_PC_MSC = -c -ML # _HOST == "_PC", _COMPILER == "_MSC" + + # redefine CFLAGS macro as: + + CFLAGS := $(CFLAGS$(_HOST)$(_COMPILER)) + + This causes CFLAGS to take on a value that corresponds to the environ- + ment in which the make is being invoked. + + The final non-standard macro expansion is of the form: + + string1{token_list}string2 + + where string1, string2 and token_list are expanded. After expansion, + string1 is prepended to each token found in token_list and string2 is + appended to each resulting token from the previous prepend. string1 + and string2 are not delimited by white space whereas the tokens in + + + +Dmake Version 4.12 2008-02-26 17 + + + + + +DMAKE(1) DMAKE(1) + + + token_list are. A null token in the token list is specified using "". + Thus using another example we have: + + test/{f1 f2}.o --> test/f1.o test/f2.o + test/ {f1 f2}.o --> test/ f1.o f2.o + test/{f1 f2} .o --> test/f1 test/f2 .o + test/{"f1" ""}.o --> test/f1.o test/.o + + and + + test/{d1 d2}/{f1 f2}.o --> test/d1/f1.o test/d1/f2.o + test/d2/f1.o test/d2/f2.o + + This last expansion is activated only when the first characters of + token_list appear immediately after the opening '{' with no intervening + white space. The reason for this restriction is the following incom- + patibility with Bourne Shell recipes. The line + + { echo hello;} + + is valid /bin/sh syntax; while + + {echo hello;} + + is not. Hence the latter triggers the enhanced macro expansion while + the former causes it to be suppressed. See the SPECIAL MACROS section + for a description of the special macros that dmake defines and under- + stands. + +RULES AND TARGETS + A makefile contains a series of entries that specify dependencies. + Such entries are called target/prerequisite or rule definitions. Each + rule definition is optionally followed by a set of lines that provide a + recipe for updating any targets defined by the rule. Whenever dmake + attempts to bring a target up to date and an explicit recipe is pro- + vided with a rule defining the target, that recipe is used to update + the target. A rule definition begins with a line having the following + syntax: + + <targets> [<attributes>] <ruleop> [<prerequisites>] [;<recipe>] + + targets is a non-empty list of targets. If the target is a special + target (see SPECIAL TARGETS section below) then it must appear alone on + the rule line. For example: + + .IMPORT .ERROR : ... + + is not allowed since both .IMPORT and .ERROR are special targets. Spe- + cial targets are not used in the construction of the dependency graph + and will not be made. + + attributes is a possibly empty list of attributes. Any attribute + defined in the ATTRIBUTES section above may be specified. All + attributes will be applied to the list of named targets in the rule + definition. No other targets will be affected. + + + NOTE: As stated earlier, if both the target list and prerequisite + list are empty but the attributes list is not, then the + + + +Dmake Version 4.12 2008-02-26 18 + + + + + +DMAKE(1) DMAKE(1) + + + specified attributes affect all targets in the makefile. + + + ruleop is a separator which is used to identify the targets from the + prerequisites. Optionally it also provides a facility for modifying + the way in which dmake handles the making of the associated targets. + In its simplest form the operator is a single ':', and need not be sep- + arated by white space from its neighboring tokens. It may additionally + be followed by any of the modifiers { !, ^, -, :, | }, where: + + + ! says execute the recipe for the associated targets once for each + out of date prerequisite. (The meaning of the runtime macro $? + is changed, see below in the RUNTIME MACROS section.) Ordinarily + the recipe is executed once for all out of date prerequisites at + the same time. + + ^ says to insert the specified prerequisites, if any, before any + other prerequisites already associated with the specified tar- + gets. In general, it is not useful to specify ^ with an empty + list of prerequisites. + + - says to clear the previous list of prerequisites before adding + the new prerequisites. Thus, + + foo : + foo : bar baz + + can be replaced by + + foo :- bar baz + + however the old form still works as expected. + + : When the rule operator is not modified by a second ':' only one + set of rules may be specified for making a target. Multiple + definitions may be used to add to the list of prerequisites that + a target depends on. However, if a target is multiply defined + only one definition may specify a recipe for making the target. + + When a target's rule operator is modified by a second ':' (:: + for example) then this definition may not be the only definition + with a recipe for the target. There may be other :: target def- + inition lines that specify a different set of prerequisites with + a different recipe for updating the target. Any such target is + made if any of the definitions find it to be out of date with + respect to the related prerequisites and the corresponding + recipe is used to update the target. By definition all '::' + recipes that are found to be out of date for are executed. + + In the following simple example, each rule has a `::' ruleop. + In such an operator we call the first `:' the operator, and the + second `:' the modifier. + + a.o :: a.c b.h + first recipe for making a.o + + a.o :: a.y b.h + second recipe for making a.o + + + +Dmake Version 4.12 2008-02-26 19 + + + + + +DMAKE(1) DMAKE(1) + + + If a.o is found to be out of date with respect to a.c then the + first recipe is used to make a.o. If it is found out of date + with respect to a.y then the second recipe is used. If a.o is + out of date with respect to b.h then both recipes are invoked to + make a.o. In the last case the order of invocation corresponds + to the order in which the rule definitions appear in the make- + file. + + | Is defined only for PERCENT rule target definitions. When spec- + ified it indicates that the following construct should be parsed + using the old semantinc meaning: + + %.o :| %.c %.r %.f ; some rule + + is equivalent to: + + %.o : %.c ; some rule + %.o : %.r ; some rule + %.o : %.f ; some rule + + Targets defined using a single `:' operator with a recipe may be rede- + fined again with a new recipe by using a `:' operator with a `:' modi- + fier. This is equivalent to a target having been initially defined + with a rule using a `:' modifier. Once a target is defined using a `:' + modifier it may not be defined again with a recipe using only the `:' + operator with no `:' modifier. In both cases the use of a `:' modifier + creates a new list of prerequisites and makes it the current prerequi- + site list for the target. The `:' operator with no recipe always modi- + fies the current list of prerequisites. Thus assuming each of the fol- + lowing definitions has a recipe attached, then: + + joe : fred ... (1) + joe :: more ... (2) + + and + + joe :: fred ... (3) + joe :: more ... (4) + + are legal and mean: add the recipe associated with (2), or (4) to the + set of recipes for joe, placing them after existing recipes for making + joe. The constructs: + + joe :: fred ... (5) + joe : more ... (6) + + and + + joe : fred ... (7) + joe : more ... (8) + + are errors since we have two sets of perfectly good recipes for making + the target. + + prerequisites is a possibly empty list of targets that must be brought + up to date before making the current target. + + recipe is a short form and allows the user to specify short rule defi- + nitions on a single line. It is taken to be the first recipe line in a + + + +Dmake Version 4.12 2008-02-26 20 + + + + + +DMAKE(1) DMAKE(1) + + + larger recipe if additional lines follow the rule definition. If the + semi-colon is present but the recipe line is empty (ie. null string) + then it is taken to be an empty rule. Any target so defined causes + target to be treated as a virtual target, see VIRTUAL TARGETS below. + +RECIPES + The traditional format used by most versions of Make defines the recipe + lines as arbitrary strings that may contain macro expansions. They + follow a rule definition line and may be spaced apart by comment or + blank lines. The list of recipe lines defining the recipe is termi- + nated by a new target definition, a macro definition, or end-of-file. + Each recipe line MUST begin with a <TAB> character (or spaces, see + .NOTABS) which may optionally be followed with one or all the following + recipe property characters '@%+-' which affect the recipe execution: + + '-' indicates that non-zero exit values (ie. errors) are to be + ignored when this recipe line is executed. + + '+' indicates that the current recipe line is to be executed using + the shell. Group recipes implicitely ignore this property. + + '%' indicates that dmake should swap itself out to secondary storage + (MSDOS only) before running the recipe. + + '@' indicates that the recipe line should NOT be echoed to the ter- + minal prior to being executed. + + '@@' is a stronger version of the previous property. The recipe line + and the output (stdout and stderr) of the executed recipe are + NOT shown on the terminal. + + Each property is off by default (ie. by default, errors are signifi- + cant, commands are echoed, no swapping is done and a shell is used only + if the recipe line contains a character found in the value of the + SHELLMETAS macro). Global settings activated via command line options + or special attribute or target names may also affect these settings. + An example recipe: + + target : + first recipe line + second recipe line, executed independent of first. + @a recipe line that is not echoed + -and one that has errors ignored + %and one that causes dmake to swap out + +and one that is executed using a shell. + + The second and new format of the recipe block begins the block with the + character '[' (the open group character) in the last non-white space + position of a line, and terminates the block with the character ']' + (the close group character) in the first non-white space position of a + line. In this form each recipe line need not have a leading TAB. This + is called a recipe group. Groups so defined are fed intact as a single + unit to a shell for execution whenever the corresponding target needs + to be updated. If the open group character '[' is preceded by one or + all of the recipe properties (-, %, @ and @@) then they apply to the + entire group in the same way that they apply to single recipe lines. + You may also specify '+' but it is redundant as a shell is already + being used to run the recipe. See the MAKING TARGETS section for a + description of how dmake invokes recipes. Here is an example of a + + + +Dmake Version 4.12 2008-02-26 21 + + + + + +DMAKE(1) DMAKE(1) + + + group recipe: + + target : + [ + first recipe line + second recipe line + tall of these recipe lines are fed to a + single copy of a shell for execution. + ] + + +BUILTIN COMMANDS + dmake supports some builtin commands. An optional leading '+' describes + that the builtin can be used also when being executed in a shell other- + wise it is only implemented when used directly. Remember that if a + character of the recipe is found in the SHELLMETAS macro the execution + of the recipe in a shell is forced. + + [+]noop [something] + The noop internal command always returns success if used but it + is not executed even though the rest of the commandline is eval- + uated. This command can be used to evaluate macro expansions at + the runtime of the recipe without starting a real commmand. + + [+]<empty recipe> + If an empty recipe line is encountered it is not executed. This + sounds more trivial than it really is because the recipe could + consist of macros that evaluated to empty or whitespace only + strings. + + echo [-n] data + This internal command prints data (with all leading whitespace + removed, but otherwise literally) to stdout. If the '-n' switch + is given no trailing newline is printed. Note that no quoting is + removed nor that escape sequences are handled. + + No special treatment of buildin commands for group recipes is imple- + mented even though the <empty recipe> will most propably also not be + evaluated by most shells that can be used to handle the recipe groups. + +TEXT DIVERSIONS + dmake supports the notion of text diversions. If a recipe line con- + tains the macro expression + + $(mktmp[,[file][,text]] data) + + then all text contained in the data expression is expanded and is writ- + ten to a temporary file. The data in the file will always be termi- + nated from a new line character. The file parameter can be used to + override the name of the temporary file. If its expanded value is not + empty it will be used instead of the unique and thread safe file name + that otherwise would be generated internally. The return value of the + macro is the name of the temporary file unless the text parameter is + defined. In this case the return value is the expanded value of text. + + data can be any text and must be separated from the 'mktmp' portion of + the macro name by white-space. The only restriction on the data text + is that it must contain a balanced number of parentheses of the same + kind as are used to initiate the $(mktmp ...) expression. For example: + + + +Dmake Version 4.12 2008-02-26 22 + + + + + +DMAKE(1) DMAKE(1) + + + $(mktmp $(XXX)) + + is legal and works as expected, but: + + $(mktmp text (to dump to file) + + is not legal. You can achieve what you wish by either defining a macro + that expands to '(' or by using {} in the macro expression; like this: + + ${mktmp text (to dump to file} + + Since the temporary file is opened when the macro containing the text + diversion expression is expanded, diversions may be nested and any + diversions that are created as part of ':=' macro expansions persist + for the duration of the dmake run. If the data text is to contain new + lines the map escape codes macro expasion can be used. For example the + expression: + + mytext:=this is a\ntest of the text diversion + all: + cat $(mktmp $(mytext:m)) + + is replaced by: + + cat /tmp/mk12294AA + + where the temporary file contains two lines both of which are termi- + nated by a new-line. A second more illustrative example generates a + response file to an MSDOS link command: + + OBJ = fred.obj mary.obj joe.obj + all : $(OBJ) + link @$(mktmp $(^:t"+\n")) + + The result of making `all' in the second example is the command: + + link @/tmp/mk02394AA + + where the temporary file contains: + + fred.obj+ + mary.obj+ + joe.obj + + The last line of the file is terminated by a new-line which is always + inserted at the end of the data string. + + If the optional file specifier is present it can be used to specify the + name of the temporary file to create. An example that would be useful + for MSDOS users with a Turbo-C compiler + + $(mktmp,turboc.cfg $(CFLAGS)) + + will place the contents of CFLAGS into a local turboc.cfg file. The + second optional argument, text, if present alters the name of the value + returned by the $(mktmp ...) macro. + + Under MS-DOS text diversions may be a problem. Many DOS tools require + that path names which contain directories use the \ character to + + + +Dmake Version 4.12 2008-02-26 23 + + + + + +DMAKE(1) DMAKE(1) + + + delimit the directories. Some users however wish to use the '/' to + delimit pathnames and use environments that allow them to do so. The + macro USESHELL is set to "yes" if the current recipe is forced to use a + shell via the .USESHELL or '+' directives, otherwise its value is "no". + The dmake startup files define the macro DIVFILE whose value is either + the value of TMPFILE or the value of TMPFILE edited to replace any '/' + characters to the appropriate value based on the current shell and + whether it will be used to execute the recipe. + + Previous versions of dmake defined text diversions using <+, +> + strings, where <+ started a text diversion and +> terminated one. + dmake is backward compatible with this construct only if the <+ and +> + appear literally on the same recipe line or in the same macro value + string. In such instances the expression: + + <+data+> + + is mapped to: + + $(mktmp data) + + which is fully output compatible with the earlier construct. <+, +> + constructs whose text spans multiple lines must be converted by hand to + use $(mktmp ...). + + If the environment variable TMPDIR is defined then the temporary file + is placed into the directory specified by that variable. A makefile + can modify the location of temporary files by defining a macro named + TMPDIR and exporting it using the .EXPORT special target. + +VIRTUAL TARGETS + Dmake allows to define targets with the sole purpose to enforce a + dependency chain that are unable to create the target, hence virtual + targets. When dmake tries to make a target, but only finds a target + definition without recipe lines, it would normally issues a "Don't know + how to make ..." error message, but if a target rule is terminated by a + semicolon and has no following recipe lines, or if it has no recipe + lines, but defines prerequisites, or if the AUGMAKE mode is enabled + (see the COMPATIBILITY section for details), the target is treated as a + virtual target and the error is suppressed. In addition to this, if the + default target does not have recipe lines it is also treated as a vir- + tual target. + + Virtual targets should not have a corresponding file therefore they + inherit the time of their newest prerequisite if they have prerequi- + sites, otherwise they get the current time assigned when being made. + If the virtual target has a corresponding file a warning is issued, but + the time stamp of that file is taken into account. The virtual target + uses the time stamp of the corresponding file if it is newer than the + one determined by the previous rule. + +SPECIAL TARGETS + This section describes the special targets that are recognized by + dmake. Some are affected by attributes and others are not. + + .ERROR If defined then the recipe associated with this target is + executed whenever an error condition is detected by + dmake. All attributes that can be used with any other + target may be used with this target. Any prerequisites + + + +Dmake Version 4.12 2008-02-26 24 + + + + + +DMAKE(1) DMAKE(1) + + + of this target will be brought up to date during its pro- + cessing. NOTE: errors will be ignored while making this + target, in extreme cases this may cause some problems. + + .EXIT If this target is encountered while parsing a makefile + then the parsing of the makefile is immediately termi- + nated at that point. + + .EXPORT All prerequisites associated with this target are assumed + to correspond to macro names and they and their values + are exported to the environment as environment strings at + the point in the makefile at which this target appears. + Any attributes specified with this target are ignored. + Only macros which have been assigned a value in the make- + file prior to the export directive are exported, macros + as yet undefined or macros whose value contains any of + the characters "+=:*" are not exported. + + Note that macros that are not expanded during the macro + assignment and contain other macros will be written into + the environment containing these other macros in the form + of $(macroname). + + .IMPORT Prerequisite names specified for this target are searched + for in the environment and defined as macros with their + value taken from the environment. If the special name + .EVERYTHING is used as a prerequisite name then all envi- + ronment variables defined in the environment are + imported. The functionality of the -E flag can be forced + by placing the construct .IMPORT : .EVERYTHING at the + start of a makefile. Similarly, by placing the construct + at the end, one can emulate the effect of the -e command + line flag. If a prerequisite name cannot be found in the + environment an error message is issued. .IMPORT accepts + the .IGNORE attribute. When given, it causes dmake to + ignore the above error. See the MACROS section for a + description of the processing of imported macro values. + + .INCLUDE Parse another makefile just as if it had been located at + the point of the .INCLUDE in the current makefile. The + list of prerequisites gives the list of makefiles to try + to read. If the list contains multiple makefiles then + they are read in order from left to right. The following + search rules are used when trying to locate the file. If + the filename is surrounded by " or just by itself then it + is searched for in the current directory. If it is not + found it is then searched for in each of the directories + specified as prerequisites of the .INCLUDEDIRS special + target. If the file name is surrounded by < and >, (ie. + <my_spiffy_new_makefile>) then it is searched for only in + the directories given by the .INCLUDEDIRS special target. + In both cases if the file name is a fully qualified name + starting at the root of the file system then it is only + searched for once, and the .INCLUDEDIRS list is ignored. + If .INCLUDE fails to find the file it invokes the infer- + ence engine to try to infer and hence make the file to be + included. In this way the file can be checked out of an + RCS repository for example. .INCLUDE accepts the + .IGNORE, .SETDIR, and .NOINFER attributes. If the + + + +Dmake Version 4.12 2008-02-26 25 + + + + + +DMAKE(1) DMAKE(1) + + + .IGNORE attribute is given and the file cannot be found + then dmake continues processing, otherwise an error mes- + sage is generated. If the .NOINFER attribute is given + and the file cannot be found then dmake will not attempt + to infer and make the file. The .SETDIR attribute causes + dmake to change directories to the specified directory + prior to attempting the include operation. If all fails + dmake attempts to make the file to be included. If mak- + ing the file fails then dmake terminates unless the + .INCLUDE directive also specified the .IGNORE attribute. + If .FIRST is specified along with .INCLUDE then dmake + attempts to include each named prerequisite and will ter- + minate the inclusion with the first prerequisite that + results in a successful inclusion. + + .INCLUDEDIRS The list of prerequisites specified for this target + defines the set of directories to search when trying to + include a makefile. + + .KEEP_STATE This special target is a synonym for the macro definition + + .KEEP_STATE := _state.mk + + It's effect is to turn on STATE keeping and to define + _state.mk as the state file. + + .MAKEFILES The list of prerequisites is the set of files to try to + read as the default makefile. By default this target is + defined as: + + .MAKEFILES : makefile.mk Makefile makefile + + + .REMOVE The recipe of this target is used whenever dmake needs to + remove intermediate targets that were made but do not + need to be kept around. Such targets result from the + application of transitive closure on the dependency + graph. + + .ROOT The internal root of the dependency graph, see section + STARTUP for details. + + .SOURCE The prerequisite list of this target defines a set of + directories to check when trying to locate a target file + name. See the section on BINDING of targets for more + information. + + .SOURCE.suff The same as .SOURCE, except that the .SOURCE.suff list is + searched first when trying to locate a file matching the + a target whose name ends in the suffix .suff. + + .SUFFIXES This deprecated special target has no special meaning. + Avoid its use. + + .TARGETS The internal targets that all user defined targets are + prerequisites of, see section STARTUP for details. + + There are a few targets that are "slightly" special: + + + + +Dmake Version 4.12 2008-02-26 26 + + + + + +DMAKE(1) DMAKE(1) + + + .INIT + .DONE + + These targets exist because of historical reasons, see the usage of + .INIT and .DONE in section "STARTUP", they can be used and defined as + ordinary targets but are special in the sense that even though they + start with a `.' they are not treated as a .<suffix> meta target (See + the AUGMAKE META RULES section for details). + + Please note that self defined targets shouldn't use the prefix `.' as + they would be handled as .<suffix> meta targets and dmake most propably + would complain about this. + + In addition to the special targets above, several other forms of tar- + gets are recognized and are considered special, their exact form and + use is defined in the sections that follow. + +SPECIAL MACROS + dmake defines a number of special macros. They are divided into three + classes: control macros, run-time macros, and function macros. The + control macros are used by dmake to configure its actions, and are the + preferred method of doing so. In the case when a control macro has the + same function as a special target or attribute they share the same name + as the special target or attribute. The run-time macros are defined + when dmake makes targets and may be used by the user inside recipes. + The function macros provide higher level functions dealing with macro + expansion and diversion file processing. + +CONTROL MACROS + To use the control macros simply assign them a value just like any + other macro. The control macros are divided into three groups: string + valued macros, character valued macros, and boolean valued macros. + + The following are all of the string valued macros. This list is + divided into two groups. The first group gives the string valued + macros that are defined internally and cannot be directly set by the + user. + + ABSMAKECMD Warning! This macro's value is differently defined for + a native Windows dmake executable (compiled with MS + Visual C++ or MinGW) and dmake for other operating sys- + tems or build with other compilers. + + In the first case its value is the absolute filename of + the executable of the current dmake process, otherwise + it is defined as the NULL string. + + INCDEPTH This macro's value is a string of digits representing + the current depth of makefile inclusion. In the first + makefile level this value is zero. + + MFLAGS Is the list of flags that were given on the command + line including a leading switch character. The -f flag + is not included in this list. + + MAKECMD Is the name with which dmake was invoked. + + MAKEDIR Is the full path to the initial directory in which + dmake was invoked. + + + +Dmake Version 4.12 2008-02-26 27 + + + + + +DMAKE(1) DMAKE(1) + + + MAKEFILE Contains the string "-f makefile" where, makefile is + the name of initial user makefile that was first read. + + MAKEFLAGS Is the same as $(MFLAGS) but has no leading switch + character. (ie. MFLAGS = -$(MAKEFLAGS)) + + MAKEMACROS Contains the complete list of macro expressions that + were specified on the command line. + + MAKETARGETS Contains the name(s) of the target(s), if any, that + were specified on the command line. + + MAKEVERSION Contains a string indicating the current dmake version + number. + + MAXPROCESSLIMIT Is a numeric string representing the maximum number of + processes that dmake can use when making targets using + parallel mode. + + NULL Is permanently defined to be the NULL string. This is + useful when comparing a conditional expression to an + NULL value. + + PWD Is the full path to the current directory in which make + is executing. + + SPACECHAR Is permanently defined to contain one space character. + This is useful when using space characters in function + macros, e.g. subst, that otherwise would get deleted + (leading/trailing spaces) or for using spaces in func- + tion macro parameters. + + TMPFILE Is set to the name of the most recent temporary file + opened by dmake. Temporary files are used for text + diversions and for group recipe processing. + + TMD Stands for "To Make Dir", and is the path from the + present directory (value of $(PWD)) to the directory + that dmake was started up in (value of $(MAKEDIR)). If + the present directory is the directory that dmake was + started up in TMD will be set to the relative path ".". + This allows to create valid paths by prepending + $(TMD)$(DIRSEPSTR) to a relative path. This macro is + modified when .SETDIR attributes are processed. TMD + will usually be a relative path with the following two + exceptions. If the relative path would go up until the + root directory or if different drive letters (DOS file + system) make a relative path impossible the absolute + path from MAKEDIR is used. + + USESHELL The value of this macro is set to "yes" if the current + recipe is forced to use a shell for its execution via + the .USESHELL or '+' directives, its value is "no" oth- + erwise. + + + The second group of string valued macros control dmake behavior and may + be set by the user. + + + + +Dmake Version 4.12 2008-02-26 28 + + + + + +DMAKE(1) DMAKE(1) + + + .DIRCACHE If set to "yes" enables the directory cache (this is + the default). If set to "no" disables the directory + cache (equivalent to -d command-line flag). + + .DIRCACHERESPCASE + If set to "yes" causes the directory cache, if enabled, + to respect file case, if set to "no" files are cached + case insensitive. By default it is set to "no" on Win- + dows as the filesystems on this operating system are + case insensitive and set to "yes" for all other operat- + ing systems. The default can be overriden, if desired. + + Note: Using case insensitive directory caching on case + sensitive file systems is a BAD idea. If in doubt use + case sensitive directory caching even on case insensi- + tive file systems as the worst case in this scenario is + that /foo/bar/ and /foo/BAR/ are cached separately + (with the same content) even though they are the same + directory. This would only happen if different targets + use different upper/lower case spellings for the same + directory and that is never a good idea. + + NAMEMAX Defines the maximum length of a filename component. + The value of the variable is initialized at startup to + the value of the compiled macro NAME_MAX. On some sys- + tems the value of NAME_MAX is too short by default. + Setting a new value for NAMEMAX will override the com- + piled value. + + .NOTABS When set to "yes" enables the use of spaces as well as + <tabs> to begin recipe lines. By default a non-group + recipe is terminated by a line without any leading + white-space or by a line not beggining with a <tab> + character. Enabling this mode modifies the first con- + dition of the above termination rule to terminate a + non-group recipe with a line that contains only + white-space. This mode does not effect the parsing of + group recipes bracketed by []. + + AUGMAKE If set to "yes" value will enable the transformation of + special meta targets to support special AUGMAKE infer- + ences (See the "AUGMAKE META RULES" and "COMPATIBILITY" + sections). + + DIRBRKSTR Contains the string of chars used to terminate the name + of a directory in a pathname. Under UNIX its value is + "/", under MSDOS its value is "/\:". + + DIRSEPSTR Contains the string that is used to separate directory + components when path names are constructed. It is + defined with a default value at startup. + + DIVFILE Is defined in the startup file and gives the name that + should be returned for the diversion file name when + used in $(mktmp ...) expansions, see the TEXT DIVERSION + section for details. + + .KEEP_STATE Assigning this macro a value tells dmake the name of + the state file to use and turns on the keeping of state + + + +Dmake Version 4.12 2008-02-26 29 + + + + + +DMAKE(1) DMAKE(1) + + + information for any targets that are brought up to date + by the make. + + GROUPFLAGS This macro gives the set of flags to pass to the shell + when invoking it to execute a group recipe. The value + of the macro is the list of flags with a leading switch + indicator. (ie. `-' under UNIX) + + GROUPSHELL This macro defines the full path to the executable + image to be used as the shell when processing group + recipes. This macro must be defined if group recipes + are used. It is assigned a default value in the + startup makefile. Under UNIX this value is /bin/sh. + + GROUPSUFFIX If defined, this macro gives the string to use as a + suffix when creating group recipe files to be handed to + the command interpreter. For example, if it is defined + as .sh, then all temporary files created by dmake will + end in the suffix .sh. Under MSDOS if you are using + command.com as your GROUPSHELL, then this suffix must + be set to .bat in order for group recipes to function + correctly. The setting of GROUPSUFFIX and GROUPSHELL + is done automatically for command.com in the startup.mk + files. + + MAKE Is defined in the startup file by default. Initially + this macro is defined to have the value "$(MAKECMD) + $(MFLAGS)". The string $(MAKE) is recognized when + using the -n switch. + + MAKESTARTUP This macro defines the full path to the initial startup + makefile. Use the -V command line option to discover + its initial value. + + MAXLINELENGTH This macro defines the maximum size of a single line of + makefile input text. The size is specified as a num- + ber, the default value is defined internally and is + shown via the -V option. A buffer of this size plus 2 + is allocated for reading makefile text. The buffer is + freed before any targets are made, thereby allowing + files containing long input lines to be processed with- + out consuming memory during the actual make. This + macro can only be used to extend the line length beyond + it's default minimum value. + + MAXPROCESS Specify the maximum number of child processes to use + when making targets. The default value of this macro + is "1" and its value cannot exceed the value of the + macro MAXPROCESSLIMIT. Setting the value of MAXPROCESS + on the command line or in the makefile is equivalent to + supplying a corresponding value to the -P flag on the + command line. If the global .SEQUENTIAL attribute is + set (or the -S command line switch is used) the value + of MAXPROCESS is fixed to "1" and cannot be changed. + + OOODMAKEMODE This macro enables a special compatibility mode needed + by the OpenOffice.org build system. If set, the switch + disables the removal of leading './' path elements dur- + ing target filename normalization (See BINDING + + + +Dmake Version 4.12 2008-02-26 30 + + + + + +DMAKE(1) DMAKE(1) + + + TARGETS). If './' appear in the pathname, but not at + the beginning of it, they are still removed by the nor- + malization. Please note that targets that are given on + the command line are going to be registered as default + targets after the startup file is read. + + PREP This macro defines the number of iterations to be + expanded automatically when processing % rule defini- + tions of the form: + + % : %.suff + + See the sections on PERCENT(%) RULES for details on how + PREP is used. + + SHELL This macro defines the full path to the executable + image to be used as the shell when processing single + line recipes. This macro must be defined if recipes + requiring the shell for execution are to be used. It + is assigned a default value in the startup makefile. + Under UNIX this value is /bin/sh. + + SHELLCMDQUOTE This macro can be used to add additional characters + before and after the command string that is passed to + the shell defined by the SHELL macro. If needed, like + for cmd.exe and command.com, it is assigned a value in + the startup file. + + SHELLFLAGS This macro gives the set of flags to pass to the shell + when invoking it to execute a single line recipe. The + value of the macro is the list of flags with a leading + switch indicator. (ie. `-' under UNIX) + + SHELLMETAS Each time dmake executes a single recipe line (not a + group recipe) the line is searched for any occurrence + of a character defined in the value of SHELLMETAS. If + such a character is found the recipe line is defined to + require a shell to ensure its correct execution. In + such instances a shell is used to invoke the recipe + line. If no match is found the recipe line is executed + without the use of a shell. + + + There is only one character valued macro defined by dmake: SWITCHAR + contains the switch character used to introduce options on command + lines. For UNIX its value is `-', and for MSDOS its value may be `/' + or `-'. The macro is internally defined and is not user setable. The + MSDOS version of dmake attempts to first extract SWITCHAR from an envi- + ronment variable of the same name. If that fails it then attempts to + use the undocumented getswitchar system call, and returns the result of + that. Under MSDOS version 4.0 you must set the value of the environ- + ment macro SWITCHAR to '/' to obtain predictable behavior. + + All boolean macros currently understood by dmake correspond directly to + the previously defined attributes. These macros provide a second way + to apply global attributes, and represent the preferred method of doing + so. They are used by assigning them a value. If the value is not a + NULL string then the boolean condition is set to on. If the value is a + NULL string then the condition is set to off. There are five + + + +Dmake Version 4.12 2008-02-26 31 + + + + + +DMAKE(1) DMAKE(1) + + + conditions defined and they correspond directly to the attributes of + the same name. Their meanings are defined in the ATTRIBUTES section + above. The macros are: .EPILOG, .IGNORE, .MKSARGS, .NOINFER, .PRE- + CIOUS, .PROLOG, .SEQUENTIAL, .SILENT, .SWAP, and .USESHELL. Assigning + any of these a non NULL value will globally set the corresponding + attribute to on. + +RUNTIME MACROS + These macros are defined when dmake is making targets, and may take on + different values for each target. $@ is defined to be the full target + name, $? is the list of all out of date prerequisites, except for the ! + ruleop, in which case it is set to the current build prerequisite + instead. $& is the list of all prerequisites, $> is the name of the + library if the current target is a library member, and $< is the list + of prerequisites specified in the current rule. If the current target + had a recipe inferred then $< is the name of the inferred prerequisite + even if the target had a list of prerequisites supplied using an + explicit rule that did not provide a recipe. In such situations $& + gives the full list of prerequisites. + + $* is defined as $(@:db) when making targets with explicit recipes and + is defined as the value of % when making targets whose recipe is the + result of an inference. In the first case $* is the target name with + no suffix, and in the second case, is the value of the matched % pat- + tern from the associated %-rule. $^ expands to the set of out of date + prerequisites taken from the current value of $<. In addition to + these, $$ expands to $, {{ expands to {, }} expands to }, and the + strings <+ and +> are recognized as respectively starting and terminat- + ing a text diversion when they appear literally together in the same + input line. + + The difference between $? and $^ can best be illustrated by an example, + consider: + + fred.out : joe amy hello + rules for making fred + + fred.out : my.c your.h his.h her.h # more prerequisites + + Assume joe, amy, and my.c are newer then fred.out. When dmake executes + the recipe for making fred.out the values of the following macros will + be: + + $@ --> fred.out + $* --> fred + $? --> joe amy my.c # note output of $? vs $^ + $^ --> joe amy + $< --> joe amy hello + $& --> joe amy hello my.c your.h his.h her.h + + +FUNCTION MACROS + dmake supports a full set of functional macros. One of these, the + $(mktmp ...) macro, is discussed in detail in the TEXT DIVERSION sec- + tion and is not covered here. The names of function macros must appear + literally after the opening $( or ${. They are not recognized if they + are the result of a recursive expansion. + + Note that some of these macros take comma separated parameters but that + + + +Dmake Version 4.12 2008-02-26 32 + + + + + +DMAKE(1) DMAKE(1) + + + these parameters must not contain literal whitespaces. Whitespaces in + macros used in these parameters are allowed. + + + $(and macroterm ...) + expands each macroterm in turn until there are no more or + one of them returns an empty string. If all expand to + non-empty strings the macro returs the string "t" other- + wise it returns an empty string. + + + $(assign expression) + Causes expression to be parsed as a macro assignment + expression and results in the specified assignment being + made. An error is issued if the assignment is not + syntatically correct. expression may contain white + space. This is in effect a dynamic macro assignment + facility and may appear anywhere any other macro may + appear. The result of the expanding a dynamic macro + assignment expression is the name of the macro that was + assigned and $(NULL) if the expression is not a valid + macro assignment expression. Some examples are: + + $(assign foo := fred) + $(assign $(ind_macro_name) +:= $(morejunk)) + + $(echo list) + Echo's the value of list. list is not expanded. + + $(eq,text_a,text_b true false) + expands text_a and text_b and compares their results. If + equal it returns the result of the expansion of the true + term, otherwise it returns the expansion of the false + term. + + $(!eq,text_a,text_b true false) + Behaves identically to the previous macro except that the + true string is chosen if the expansions of the two + strings are not equal + + $(foreach,var,list data) + Implements iterative macro expansion over data using var + as the iterator taking on values from list. var and list + are expanded and the result is the concatenation of + expanding data with var being set to each whitespace sep- + arated token from list. For example: + + list = a b c + all :; echo [$(foreach,i,$(list) [$i])] + + will output + + [[a] [b] [c]] + + The iterator variable is defined as a local variable to + this foreach instance. The following expression illus- + trates this: + + $(foreach,i,$(foreach,i,$(sort c a b) root/$i) [$i/f.h]) + + + +Dmake Version 4.12 2008-02-26 33 + + + + + +DMAKE(1) DMAKE(1) + + + when evaluated the result is: + + [root/a/f.h] [root/b/f.h] [root/c/f.h] + + The specification of list must be a valid macro expres- + sion, such as: + + $($(assign list=a b c)) + $(sort d a b c) + $(echo a b c) + + and cannot just be the list itself. That is, the follow- + ing foreach expression: + + $(foreach,i,a b c [$i]) + + yields: + + "b c [a]" + + when evaluated. + + $(nil expression) + Always returns the value of $(NULL) regardless of what + expression is. This function macro can be used to dis- + card results of expanding macro expressions. + + $(normpath list) + Will return the normalized path names of all white-space + separated tokens in list. Quotes can be used to normalize + path names that contain white-space characters. On cygwin + the result honors the setting of .WINPATH to determine + the output format of the returned path names. + + $(normpath,para list) + Same as above except that the expanded value of para is + used to override the .WINPATH setting. + + $(not macroterm) + expands macroterm and returs the string "t" if the result + of the expansion is the empty string; otherwise, it + returns the empty string. + + $(null,text true false) + expands the value of text. If it is NULL then the macro + returns the value of the expansion of true and the expan- + sion of false otherwise. The terms true, and false must + be strings containing no white-space. + + $(!null,text true false) + Behaves identically to the previous macro except that the + true string is chosen if the expansion of text is not + NULL. + + $(or macroterm ...) + expands each macroterm in turn and returs the empty + string if each term expands to the empty string; other- + wise, it returs the string "t". + + + + +Dmake Version 4.12 2008-02-26 34 + + + + + +DMAKE(1) DMAKE(1) + + + $(shell command) + is a shell escape macro. It runs command as if it were + part of a recipe and returns, separated by a single + space, all the non-white space terms written to stdout by + the command. For example: + + $(shell ls *.c) + + will return "a.c b.c c.c d.c" if the files exist in the + current directory. The recipe modification flags [+@%-] + are honored if they appear as the first characters in the + command. For example: + + $(shell +ls *.c) + + will run the command using the current shell. + + Note that if the macro is part of a recipe it will be + evaluated after all previous recipe lines have been exe- + cuted. For obvious reasons it will be evaluated before + the current recipe line or group recipe is executed. + + $(shell,expand command) + Is an extension to the $(shell command) function macro + that expands the result of running command. + + $(sort list) + Will take all white-space separated tokens in list and + will return their sorted equivalent list. + + $(strip data) + Will replace all strings of white-space in data by a sin- + gle space. + + $(subst,pat,replacement data) + Will search for pat in data and will replace any occur- + rence of pat with the replacement string. The expansion + + $(subst,.o,.c $(OBJECTS)) + + is equivalent to: + + $(OBJECTS:s/.o/.c/) + + + $(uniq list) + Will take all white-space separated tokens in list and + will return their sorted equivalent list containing no + duplicates. + + For historic reasons dmake treats the following case slightly special: + + $(name something) + + If it encounters a macro with a whitespace after name and name is not + literally one of the above mentioned function macro identifiers then + dmake will return the recursively expanded value of $(name). The + remaining something part will be expanded but the result will be dis- + carded. The use of this special feature is deprecated and should not be + + + +Dmake Version 4.12 2008-02-26 35 + + + + + +DMAKE(1) DMAKE(1) + + + used. + + +CONDITIONAL MACROS + dmake supports conditional macros. These allow the definition of tar- + get specific macro values. You can now say the following: + + target ?= MacroName MacroOp Value + + This creates a definition for MacroName whose value is Value only when + target is being made. You may use a conditional macro assignment any- + where that a regular macro assignment may appear, including as the + value of a $(assign ...) macro. + + The new definition is associated with the most recent cell definition + for target. If no prior definition exists then one is created. The + implications of this are immediately evident in the following example: + + foo := hello + + all : cond;@echo "all done, foo=[$(foo)] bar=[$(bar)]" + + cond ?= bar := global decl + + cond .SETDIR=unix::;@echo $(foo) $(bar) + cond ?= foo := hi + + cond .SETDIR=msdos::;@echo $(foo) $(bar) + cond ?= foo := hihi + + The first conditional assignment creates a binding for 'bar' that is + activated when 'cond' is made. The bindings following the :: defini- + tions are activated when their respective recipe rules are used. Thus + the first binding serves to provide a global value for 'bar' while any + of the cond :: rules are processed, and the local bindings for 'foo' + come into effect when their associated :: rule is processed. + + Conditionals for targets of .UPDATEALL are all activated before the + target group is made. Assignments are processed in order. Note that + the value of a conditional macro assignment is NOT AVAILABLE until the + associated target is made, thus the construct + + mytarget ?= bar := hello + mytarget ?= foo := $(bar) + + results in $(foo) expanding to "", if you want the result to be "hello" + you must use: + + mytarget ?= bar := hello + mytarget ?= foo = $(bar) + + Once a target is made any associated conditional macros are deactivated + and their values are no longer available. Activation occurrs after all + inference, and .SETDIR directives have been processed and after $@ is + assigned, but before prerequisites are processed; thereby making the + values of conditional macro definitions available during construction + of prerequisites. + + If a %-meta rule target has associated conditional macro assignments, + + + +Dmake Version 4.12 2008-02-26 36 + + + + + +DMAKE(1) DMAKE(1) + + + and the rule is chosen by the inference algorithm then the conditional + macro assignments are inferred together with the associated recipe. + +DYNAMIC PREREQUISITES + dmake looks for prerequisites whose names contain macro expansions dur- + ing target processing. Any such prerequisites are expanded and the + result of the expansion is used as the prerequisite name. As an exam- + ple the line: + + fred : $$@.c + + causes the $$@ to be expanded when dmake is making fred, and it + resolves to the target fred. This enables dynamic prerequisites to be + generated. The value of @ may be modified by any of the valid macro + modifiers. So you can say for example: + + fred.out : $$(@:b).c + + where the $$(@:b) expands to fred. Note the use of $$ instead of $ to + indicate the dynamic expansion, this is due to the fact that the rule + line is expanded when it is initially parsed, and $$ then returns $ + which later triggers the dynamic prerequisite expansion. Dynamic macro + expansion is performed in all user defined rules, and the special tar- + gets .SOURCE*, and .INCLUDEDIRS. + + NOTE: The use of a $ as part of a prerequisite or target name is + strongly discouraged as the runtime macros (like $@) are expanded when + used in a recipe line so that the $ is interpreted as a macro identi- + fier and not as a character of the filename leading to invalid runtime + macros. In addition to this no filename normalization is done for pre- + requisites and targets that contain $ characters. Nevertheless it is + possible to use $ in prerequisites by using $$$$ but this is not recom- + mended and can lead to surprising results. + + If dynamic macro expansion results in multiple white space separated + tokens then these are inserted into the prerequisite list inplace of + the dynamic prerequisite. Due to the recursive nature of macro expan- + sion the prerequisite list is fully expanded even if the dynamic pre- + requisite contained other runtime macros. + +BINDING TARGETS + This operation takes a target name and binds it to an existing file, if + possible. dmake makes a distinction between the internal target name + of a target and its associated external file name. Thus it is possible + for a target's internal name and its external file name to differ. To + perform the binding, the following set of rules is used. Assume that + we are trying to bind a target whose name is of the form X.suff, where + .suff is the suffix and X is the stem portion (ie. that part which con- + tains the directory and the basename). dmake takes this target name + and performs a series of search operations that try to find a suitably + named file in the external file system. The search operation is user + controlled via the settings of the various .SOURCE targets. + + 1. If target has the .SYMBOL attribute set then look for it + in the library. If found, replace the target name with + the library member name and continue with step 2. If the + name is not found then return. + + 2. Extract the suffix portion (that following the `.') of + the target name. If the suffix is not null, look up the + + + +Dmake Version 4.12 2008-02-26 37 + + + + + +DMAKE(1) DMAKE(1) + + + special target .SOURCE.<suff> (<suff> is the suffix). If + the special target exists then search each directory + given in the .SOURCE.<suff> prerequisite list for the + target. If the target's suffix was null (ie. .suff was + empty) then perform the above search but use the special + target .SOURCE.NULL instead. If at any point a match is + found then terminate the search. If a directory in the + prerequisite list is the special name `.NULL ' perform a + search for the full target name without prepending any + directory portion (ie. prepend the NULL directory). + + 3. The search in step 2. failed. Repeat the same search but + this time use the special target .SOURCE. (a default + target of '.SOURCE : .NULL' is defined by dmake at + startup, and is user redefinable) + + 4. The search in step 3. failed. If the target has the + library member attribute (.LIBMEMBER) set then try to + find the target in the library which was passed along + with the .LIBMEMBER attribute (see the MAKING LIBRARIES + section). The bound file name assigned to a target which + is successfully located in a library is the same name + that would be assigned had the search failed (see 5.). + + 5. The search failed. Either the target was not found in + any of the search directories or no applicable .SOURCE + special targets exist. If applicable .SOURCE special + targets exist, but the target was not found, then dmake + assigns the first name searched as the bound file name. + If no applicable .SOURCE special targets exist, then the + full original target name becomes the bound file name. + + There is potential here for a lot of search operations. The trick is + to define .SOURCE.x special targets with short search lists and leave + .SOURCE as short as possible. The search algorithm has the following + useful side effect. When a target having the .LIBMEMBER (library mem- + ber) attribute is searched for, it is first searched for as an ordinary + file. When a number of library members require updating it is desir- + able to compile all of them first and to update the library at the end + in a single operation. If one of the members does not compile and + dmake stops, then the user may fix the error and make again. dmake + will not remake any of the targets whose object files have already been + generated as long as none of their prerequisite files have been modi- + fied as a result of the fix. + + When dmake constructs target (and prerequisite) pathnames they are nor- + malized to the shortest (or most natural, see below for the cygwin + case) representation. Substrings like './' or of the form 'baz/..' are + removed and multiple slashes are collapsed to one unless they are at + the beginning of the pathname. Leading slashes are normalized according + to POSIX rules, i.e. more than two leading slashes are reduced to one + slash and a leading '//' is kept as it might have a special meaning. + For example "./foo", "bar/../foo" and foo are recognized as the same + file. This may result in somewhat unexpected values of the macro + expansion of runtime macros like $@, but is infact the corect result. + + NOTE: A cygwin dmake executable will accept DOS like pathnames with + drive letters and cygwin POSIX pathnames and normalize them into its + natural POSIX representation. This might result in even more surpris- + ing values of runtime macros. + + + +Dmake Version 4.12 2008-02-26 38 + + + + + +DMAKE(1) DMAKE(1) + + + When defining .SOURCE and .SOURCE.x targets the construct + + .SOURCE : + .SOURCE : fred gery + + is equivalent to + + .SOURCE :- fred gery + + dmake correctly handles the UNIX Make variable VPATH. By definition + VPATH contains a list of ':' separated directories to search when look- + ing for a target. dmake maps VPATH to the following special rule: + + .SOURCE :^ $(VPATH:s/:/ /) + + Which takes the value of VPATH and sets .SOURCE to the same set of + directories as specified in VPATH. + +PERCENT(%) RULES AND MAKING INFERENCES + When dmake makes a target, the target's set of prerequisites (if any) + must exist and the target must have a recipe which dmake can use to + make it. If the makefile does not specify an explicit recipe for the + target then dmake uses special rules to try to infer a recipe which it + can use to make the target. Previous versions of Make perform this + task by using rules that are defined by targets of the form .<suf- + fix>.<suffix> (this is still supported, see "AUGMAKE META RULES") or by + using the not supported by dmake .SUFFIXES list of suffixes (see "SPE- + CIAL TARGETS" for more details about .SUFFIXES). The exact workings of + this mechanism were sometimes difficult to understand and often limit- + ing in their usefulness. Instead, dmake supports the concept of %-meta + rules. The syntax and semantics of these rules differ from standard + rule lines as follows: + + <%-targets> [<attributes>] <ruleop> [<%-prereqs>] [;<recipe>] + + where %-targets are one or more targets containing exactly a single `%' + sign, attributes is a list (possibly empty) of attributes, ruleop is + the standard set of rule operators, %-prereqs , if present, is a list + of prerequisites containing zero or more `%' signs, and recipe, if + present, is the first line of the recipe. + + If more than one %-target is present this line is equivalent to a repe- + tition of the whole [<attributes>] <ruleop> [<%-prereqs>] [;<recipe>] + sequence for each %-target, i.e. it is possible to specify the same + rule for multiple %-targets. Because of this following only speaks + about <%-target> as %-targets are divided into multiple definitions + with a single %-target. + + NOTE: As multiple %-targets didn't work reliably with dmake versions + prior to 4.5 unless the rule operator `|:' was used we currently issue + a warning stating that it now works. + + The %-target defines a pattern against which a target whose recipe is + being inferred gets matched. The pattern match goes as follows: all + chars are matched exactly from left to right up to but not including + the % sign in the pattern, % then matches the longest string from the + actual target name not ending in the suffix given after the % sign in + the pattern. Consider the following examples: + + %.c matches fred.c but not joe.c.Z + dir/%.c matches dir/fred.c but not dd/fred.c + fred/% matches fred/joe.c but not f/joe.c + % matches anything + + + + +Dmake Version 4.12 2008-02-26 39 + + + + + +DMAKE(1) DMAKE(1) + + + In each case the part of the target name that matched the % sign is + retained and is substituted for any % signs in the prerequisite list of + the %-meta rule when the rule is selected during inference and dmake + constructs the new dependency. + + Please note, that only the first, non-indirect, prerequisite of the + list is used for the inference mechanism. If more than one non-indirect + prerequisite is given a warning is issued and all but the first non- + indirect prerequisites are ignored. See below for a description of + indirect prerequisites. + + As an example the following %-meta rules describe the following: + + %.c : %.y ; recipe... + + describes how to make any file ending in .c if a corresponding file + ending in .y can be found. + + foo%.o : fee%.k ; recipe... + + is used to describe how to make fooxxxx.o from feexxxx.k. + + %.a :; recipe... + + describes how to make a file whose suffix is .a without inferring any + prerequisites. + + %.c : %.y 'yaccsrc/%.y' ; recipe... + + matches the corresponding .y file as prerequisite and additionally + another .y file in the yaccsrc subdirectory as indirect prerequisite. + Another interesting example is: + + % : RCS/%,v ; co $< + + which describes how to take any target and check it out of the RCS + directory if the corresponding file exists in the RCS directory. The + equivalent SCCS rule would be: + + % : s.% ; get $< + + + The previous RCS example defines an infinite rule, because it says how + to make anything from RCS/%,v, and anything also includes RCS/fred.c,v. + To limit the size of the graph that results from such rules dmake uses + the macro variable PREP (stands for % repetition). By default the + value of this variable is 0, which says that no repetitions of a %-rule + are to be generated. If it is set to something greater than 0, then + that many repetitions of any infinite %-rule are allowed. If in the + above example PREP was set to 1, then dmake would generate the depen- + dency graph: + + % --> RCS/%,v --> RCS/RCS/%,v,v + + Where each link is assigned the same recipe as the first link. PREP + should be used only in special cases, since it may result in a large + increase in the number of possible prerequisites tested. dmake further + assumes that any target that has no suffix can be made from a prerequi- + site that has at least one suffix. + + dmake supports dynamic prerequisite generation for prerequisites of + %-meta rules. This is best illustrated by an example. The RCS rule + shown above can infer how to check out a file from a corresponding RCS + file only if the target is a simple file name with no directory + + + +Dmake Version 4.12 2008-02-26 40 + + + + + +DMAKE(1) DMAKE(1) + + + information. That is, the above rule can infer how to find + RCS/fred.c,v from the target fred.c, but cannot infer how to find + srcdir/RCS/fred.c,v from srcdir/fred.c because the above rule will + cause dmake to look for RCS/srcdir/fred.c,v; which does not exist + (assume that srcdir has its own RCS directory as is the common case). + + A more versatile formulation of the above RCS check out rule is the + following: + + % : $$(@:d)RCS/$$(@:f),v : co $@ + + This rule uses the dynamic macro $@ to specify the prerequisite to try + to infer. During inference of this rule the macro $@ is set to the + value of the target of the %-meta rule and the appropriate prerequisite + is generated by extracting the directory portion of the target name (if + any), appending the string RCS/ to it, and appending the target file + name with a trailing ,v attached to the previous result. + + dmake can also infer indirect prerequisites. An inferred target can + have a list of prerequisites added that will not show up in the value + of $< but will show up in the value of $? and $&. Indirect prerequi- + sites are specified in an inference rule by quoting the prerequisite + with single quotes. For example, if you had the explicit dependency: + + fred.o : fred.c ; rule to make fred.o + fred.o : local.h + + then this can be inferred for fred.o from the following inference rule: + + %.o : %.c 'local.h' ; makes a .o from a .c + + You may infer indirect prerequisites that are a function of the value + of '%' in the current rule. The meta-rule: + + %.o : %.c '$(INC)/%.h' ; rule to make a .o from a .c + + infers an indirect prerequisite found in the INC directory whose name + is the same as the expansion of $(INC), and the prerequisite name + depends on the base name of the current target. The set of indirect + prerequisites is attached to the meta rule in which they are specified + and are inferred only if the rule is used to infer a recipe for a tar- + get. They do not play an active role in driving the inference algo- + rithm. The construct: + + %.o :| %.c %.f 'local.h'; recipe + + is equivalent to: + + %.o : %.c 'local.h' ; recipe + %.o : %.f 'local.h' ; recipe + + + If any of the attributes .EPILOG, .IGNORE, .LIBRARY, .NOSTATE, .PHONY, + .PRECIOUS, .PROLOG, .SETDIR, .SILENT, .SWAP, .USESHELL and .WINPATH are + given for a %-rule then when that rule is bound to a target as the + result of an inference, the target's set of attributes is augmented by + the attributes from the above set that are specified in the bound + %-rule. Other attributes specified for %-meta rules are not inherited + by the target. The .SETDIR attribute is treated in a special way. If + the target already had a .SETDIR attribute set then dmake changes to + that directory prior to performing the inference. During inference any + .SETDIR attributes for the inferred prerequisite are honored. The + directories must exist for a %-meta rule to be selected as a possible + inference path. If the directories do not exist no error message is + + + +Dmake Version 4.12 2008-02-26 41 + + + + + +DMAKE(1) DMAKE(1) + + + issued, instead the corresponding path in the inference graph is + rejected. + + dmake bases all of its inferences on the inference graph constructed + from the %-rules defined in the makefile. It knows exactly which tar- + gets can be made from which prerequisites by making queries on the + inference graph. + + For a %-meta rule to be inferred as the rule whose recipe will be used + to make a target, the target's name must match the %-target pattern, + and any inferred %-prerequisite must already exist or have an explicit + recipe so that the prerequisite can be made. Without transitive clo- + sure on the inference graph the above rule describes precisely when an + inference match terminates the search. If transitive closure is + enabled (the usual case), and a prerequisite does not exist or cannot + be made, then dmake invokes the inference algorithm recursively on the + prerequisite to see if there is some way the prerequisite can be manu- + factured. For, if the prerequisite can be made then the current target + can also be made using the current %-meta rule. This means that there + is no longer a need to give a rule for making a .o from a .y if you + have already given a rule for making a .o from a .c and a .c from a .y. + In such cases dmake can infer how to make the .o from the .y via the + intermediary .c and will remove the .c when the .o is made. Transitive + closure can be disabled by giving the -T switch on the command line. + + A word of caution. dmake bases its transitive closure on the %-meta + rule targets. When it performs transitive closure it infers how to + make a target from a prerequisite by performing a pattern match as if + the potential prerequisite were a new target. The set of rules: + + %.o : %.c ; rule for making .o from .c + %.c : %.y ; rule for making .c from .y + % : RCS/%,v ; check out of RCS file + + will, by performing transitive closure, allow dmake to infer how to + make a .o from a .y using a .c as an intermediate temporary file. + Additionally it will be able to infer how to make a .y from an RCS + file, as long as that RCS file is in the RCS directory and has a name + which ends in .y,v. The transitivity computation is performed dynami- + cally for each target that does not have a recipe. This has potential + to be costly if the %-meta rules are not carefully specified. The + .NOINFER attribute is used to mark a %-meta node as being a final tar- + get during inference. Any node with this attribute set will not be + used for subsequent inferences. As an example the node RCS/%,v is + marked as a final node since we know that if the RCS file does not + exist there likely is no other way to make it. Thus the standard + startup makefile contains an entry similar to: + .NOINFER : RCS/%,v + Thereby indicating that the RCS file is the end of the inference chain. + Whenever the inference algorithm determines that a target can be made + from more than one prerequisite and the inference chains for the two + methods are the same length the algorithm reports an ambiguity and + prints the ambiguous inference chains. + + dmake tries to remove intermediate files resulting from transitive clo- + sure if the file is not marked as being PRECIOUS, or the -u flag was + not given on the command line, and if the inferred intermediate did not + previously exist. Intermediate targets that existed prior to being + made are never removed. This is in keeping with the philosophy that + dmake should never remove things from the file system that it did not + add. If the special target .REMOVE is defined and has a recipe then + dmake constructs a list of the intermediate files to be removed and + makes them prerequisites of .REMOVE. It then makes .REMOVE thereby + removing the prerequisites if the recipe of .REMOVE says to. Typically + + + +Dmake Version 4.12 2008-02-26 42 + + + + + +DMAKE(1) DMAKE(1) + + + .REMOVE is defined in the startup file as: + + .REMOVE :; $(RM) $< + +AUGMAKE META RULES + As a subclass of the meta targets that is actually mapped to %-meta + rules dmake understands several SYSV AUGMAKE targets transformations. + This .<suffix> special target construct transforms into the following + %-meta rules: + + .suff :; recipe + + gets mapped into: + + % : %.suff; recipe + + + dmake also supports the old format special target .<suffix>.<suffix> by + identifying any rules of this form and mapping them to the appropriate + %-rule. So for example if an old makefile contains the construct: + + .c.o :; cc -c $< -o $@ + + dmake maps this into the following %-rule: + + %.o : %.c; cc -c $< -o $@ + + The following SYSV AUGMAKE special targets transformation must be + enabled by providing the -A flag on the command line or by setting the + value of AUGMAKE to non-NULL. The construct + + .c~.o :; recipe + + gets mapped into: + + %.o : s.%.c ; recipe + + In general, a special target of the form .<str>~ is replaced by the + %-rule construct s.%.<str>, thereby providing support for the syntax + used by SYSV AUGMAKE for providing SCCS support. When enabled, these + mappings allow processing of existing SYSV makefiles without modifica- + tions. + +MAKING TARGETS + In order to update a target dmake must execute a recipe. When a recipe + needs to be executed it is first expanded so that any macros in the + recipe text are expanded, and it is then either executed directly or + passed to a shell. dmake supports two types of recipes. The regular + recipes and group recipes. + + When a regular recipe is invoked dmake executes each line of the recipe + separately using a new copy of a shell if a shell is required. Thus + effects of commands do not generally persist across recipe lines (e.g. + cd requests in a recipe line do not carry over to the next recipe + line). This is true even in environments such as MSDOS, where dmake + internally sets the current working director to match the directory it + was in before the command was executed. + + The decision on whether a shell is required to execute a command is + based on the value of the macro SHELLMETAS or on the specification of + '+' or .USESHELL for the current recipe or target respectively. If any + character in the value of SHELLMETAS is found in the expanded recipe + text-line or the use of a shell is requested explicitly via '+' or + .USESHELL then the command is executed using a shell, otherwise the + + + +Dmake Version 4.12 2008-02-26 43 + + + + + +DMAKE(1) DMAKE(1) + + + command is executed directly. The shell that is used for execution is + given by the value of the macro SHELL. The flags that are passed to + the shell are given by the value of SHELLFLAGS. Thus dmake constructs + the command line: + + $(SHELL) $(SHELLFLAGS) $(expanded_recipe_command) + + If the $(SHELLCMDQUOTE) macro is set its value is inserted before and + after the $(expanded_recipe_command) string. + + Normally dmake writes the command line that it is about to invoke to + standard output. If the .SILENT attribute is set for the target or for + the recipe line (via @), then the recipe line is not echoed. + + Group recipe processing is similar to that of regular recipes, except + that a shell is always invoked. The shell that is invoked is given by + the value of the macro GROUPSHELL, and its flags are taken from the + value of the macro GROUPFLAGS. If a target has the .PROLOG attribute + set then dmake prepends to the shell script the recipe associated with + the special target .GROUPPROLOG, and if the attribute .EPILOG is set as + well, then the recipe associated with the special target .GROUPEPILOG + is appended to the script file. This facility can be used to always + prepend a common header and common trailer to group recipes. Group + recipes are echoed to standard output just like standard recipes, but + are enclosed by lines beginning with [ and ]. + + The recipe flags [+,-,%,@] are recognized at the start of a recipe line + even if they appear in a macro. For example: + + SH = + + all: + $(SH)echo hi + + is completely equivalent to writing + + SH = + + all: + +echo hi + + + The last step performed by dmake prior to running a recipe is to set + the macro CMNDNAME to the name of the command to execute (determined by + finding the first white-space ending token in the command line). It + then sets the macro CMNDARGS to be the remainder of the line. dmake + then expands the macro COMMAND which by default is set to + + COMMAND = $(CMNDNAME) $(CMNDARGS) + + The result of this final expansion is the command that will be exe- + cuted. The reason for this expansion is to allow for a different + interface to the argument passing facilities (esp. under DOS) than that + provided by dmake. You can for example define COMMAND to be + + COMMAND = $(CMNDNAME) @$(mktmp $(CMNDARGS)) + + which dumps the arguments into a temporary file and runs the command + + $(CMNDNAME) @/tmp/ASAD23043 + + which has a much shorter argument list. It is now up to the command to + use the supplied argument as the source for all other arguments. As an + optimization, if COMMAND is not defined dmake does not perform the + above expansion. On systems, such as UNIX, that handle long command + lines this provides a slight saving in processing the makefiles. + + + +Dmake Version 4.12 2008-02-26 44 + + + + + +DMAKE(1) DMAKE(1) + + +MAKING LIBRARIES + Libraries are easy to maintain using dmake. A library is a file con- + taining a collection of object files. Thus to make a library you sim- + ply specify it as a target with the .LIBRARY attribute set and specify + its list of prerequisites. The prerequisites should be the object mem- + bers that are to go into the library. When dmake makes the library + target it uses the .LIBRARY attribute to pass to the prerequisites the + .LIBMEMBER attribute and the name of the library. This enables the + file binding mechanism to look for the member in the library if an + appropriate object file cannot be found. dmake now supports Elf + libraries on systems that support Elf and hence supports, on those sys- + tems, long member file names. A small example best illustrates this. + + mylib.a .LIBRARY : mem1.o mem2.o mem3.o + rules for making library... + # remember to remove .o's when lib is made + + # equivalent to: '%.o : %.c ; ...' + .c.o :; rules for making .o from .c say + + dmake will use the .c.o rule for making the library members if appro- + priate .c files can be found using the search rules. NOTE: this is + not specific in any way to C programs, they are simply used as an exam- + ple. + + dmake tries to handle the old library construct format in a sensible + way. The construct lib(member.o) is separated and the lib portion is + declared as a library target. The new target is defined with the + .LIBRARY attribute set and the member.o portion of the construct is + declared as a prerequisite of the lib target. If the construct + lib(member.o) appears as a prerequisite of a target in the makefile, + that target has the new name of the lib assigned as its prerequisite. + Thus the following example: + + a.out : ml.a(a.o) ml.a(b.o); $(CC) -o $@ $< + + .c.o :; $(CC) -c $(CFLAGS) -o $@ $< + %.a: + ar rv $@ $? + ranlib $@ + rm -rf $? + + constructs the following dependency graph. + + a.out : ml.a; $(CC) -o $@ $< + ml.a .LIBRARY : a.o b.o + + %.o : %.c ; $(CC) -c $(CFLAGS) -o $@ $< + %.a : + ar rv $@ $? + ranlib $@ + rm -rf $? + + and making a.out then works as expected. + + The same thing happens for any target of the form lib((entry)). These + targets have an additional feature in that the entry target has the + .SYMBOL attribute set automatically. + + NOTE: If the notion of entry points is supported by the archive and by + dmake (currently not the case) then dmake will search the archive for + the entry point and return not only the modification time of the member + which defines the entry but also the name of the member file. This + name will then replace entry and will be used for making the member + + + +Dmake Version 4.12 2008-02-26 45 + + + + + +DMAKE(1) DMAKE(1) + + + file. Once bound to an archive member the .SYMBOL attribute is removed + from the target. This feature is presently disabled as there is little + standardization among archive formats, and we have yet to find a make- + file utilizing this feature (possibly due to the fact that it is unim- + plemented in most versions of UNIX Make). + + Finally, when dmake looks for a library member it must first locate the + library file. It does so by first looking for the library relative to + the current directory and if it is not found it then looks relative to + the current value of $(TMD). This allows commonly used libraries to be + kept near the root of a source tree and to be easily found by dmake. + +KEEP STATE + dmake supports the keeping of state information for targets that it + makes whenever the macro .KEEP_STATE is assigned a value. The value of + the macro should be the name of a state file that will contain the + state information. If state keeping is enabled then each target that + does not poses the .NOSTATE attribute will have a record written into + the state file indicating the target's name, the current directory, the + command used to update the target, and which, if any, :: rule is being + used. When you make this target again if any of this information does + not match the previous settings and the target is not out dated it will + still be re-made. The assumption is that one of the conditions above + has changed and that we wish to remake the target. For example, state + keeping is used in the maintenance of dmake to test compile different + versions of the source using different compilers. Changing the com- + piler causes the compilation flags to be modified and hence all sources + to be recompiled. + + The state file is an ascii file and is portable, however it is not in + human readable form as the entries represent hash keys of the above + information. + + The Sun Microsystem's Make construct + + .KEEP_STATE : + + is recognized and is mapped to .KEEP_STATE:=_state.mk. The dmake ver- + sion of state keeping does not include scanning C source files for + dependencies like Sun Make. This is specific to C programs and it was + felt that it does not belong in make. dmake instead provides the tool, + cdepend, to scan C source files and to produce depedency information. + Users are free to modify cdepend to produce other dependency files. + (NOTE: cdepend does not come with the distribution at this time, but + will be available in a patch in the near future) + +MULTI PROCESSING + If the architecture supports it then dmake is capable of making a tar- + get's prerequisites in parallel. dmake will make as much in parallel + as it can and use a number of child processes up to the maximum speci- + fied by MAXPROCESS or by the value supplied to the -P command line + flag. A parallel make is enabled by setting the value of MAXPROCESS + (either directly or via -P option) to a value which is > 1. dmake + guarantees that all dependencies as specified in the makefile are hon- + ored. A target will not be made until all of its prerequisites have + been made. Note that when you specify -P 4 then four child processes + are run concurrently but dmake actually displays the fifth command it + will run immediately upon a child process becomming free. This is an + artifact of the method used to traverse the dependency graph and cannot + be removed. If a parallel make is being performed then the following + restrictions on parallelism are enforced. + + 1. Individual recipe lines in a non-group recipe are per- + formed sequentially in the order in which they are + + + +Dmake Version 4.12 2008-02-26 46 + + + + + +DMAKE(1) DMAKE(1) + + + specified within the makefile and in parallel with the + recipes of other targets. + + 2. If a target contains multiple recipe definitions (cf. :: + rules) then these are performed sequentially in the order + in which the :: rules are specified within the makefile + and in parallel with the recipes of other targets. + + 3. If a target rule contains the `!' modifier, then the + recipe is performed sequentially for the list of outdated + prerequisites and in parallel with the recipes of other + targets. + + 4. If a target has the .SEQUENTIAL attribute set then all of + its prerequisites are made sequentially relative to one + another (as if MAXPROCESS=1), but in parallel with other + targets in the makefile. + + Note: If you specify a parallel make then the order of target update + and the order in which the associated recipes are invoked will not cor- + respond to that displayed by the -n flag. + +CONDITIONALS + dmake supports a makefile construct called a conditional. It allows + the user to conditionally select portions of makefile text for input + processing and to discard other portions. This becomes useful for + writing makefiles that are intended to function for more than one tar- + get host and environment. The conditional expression is specified as + follows: + + .IF expression + ... if text ... + .ELIF expression + ... if text ... + .ELSE + ... else text ... + .END + + The .ELSE and .ELIF portions are optional, and the conditionals may be + nested (ie. the text may contain another conditional). .IF, .ELSE, + and .END may appear anywhere in the makefile, but a single conditional + expression may not span multiple makefiles. + + expression can be one of the following forms: + + String evaluation + <text> | <text> == <text> | <text> != <text> + + Numeric evaluation + <text> <= <text> | <text> >= <text> + + Boolean evaluation + ( <text> ) | <text> || <text> | <text> && <text> + + where text is either text or a macro expression. In any case, before + the comparison is made, the expression is expanded. The text portions + are then selected and compared. In the case of the numeric comparisons + enclosing quotes are removed after expanding the expressions and the + leading numerical parts are converted to an integer number. If no + numerical part is found this results to 0 (zero). The string "12ab" for + example evaluates to the number 12. Expressions can be nested with () + and the use of || or &&. White space at the start and end of the text + portion is discarded before the comparison. This means that a macro + that evaluates to nothing but white space is considered a NULL value + + + +Dmake Version 4.12 2008-02-26 47 + + + + + +DMAKE(1) DMAKE(1) + + + for the purpose of the comparison. In the first case the expression + evaluates TRUE if the text is not NULL otherwise it evaluates FALSE. + The remaining two cases both evaluate the expression on the basis of a + string comparison. If a macro expression needs to be equated to a NULL + string then compare it to the value of the macro $(NULL). You can use + the $(shell ...) macro to construct more complex test expressions. + +EXAMPLES + # A simple example showing how to use make + # + prgm : a.o b.o + cc a.o b.o -o prgm + a.o : a.c g.h + cc a.c -o $@ + b.o : b.c g.h + cc b.c -o $@ + + In the previous example prgm is remade only if a.o and/or b.o is out of + date with respect to prgm. These dependencies can be stated more con- + cisely by using the inference rules defined in the standard startup + file. The default rule for making .o's from .c's looks something like + this: + + %.o : %.c; cc -c $(CFLAGS) -o $@ $< + + Since there exists a rule (defined in the startup file) for making .o's + from .c's dmake will use that rule for manufacturing a .o from a .c and + we can specify our dependencies more concisely. + + prgm : a.o b.o + cc -o prgm $< + a.o b.o : g.h + + A more general way to say the above using the new macro expansions + would be: + + SRC = a b + OBJ = {$(SRC)}.o + + prgm : $(OBJ) + cc -o $@ $< + + $(OBJ) : g.h + + If we want to keep the objects in a separate directory, called objdir, + then we would write something like this. + + SRC = a b + OBJ = {$(SRC)}.o + + prgm : $(OBJ) + cc $< -o $@ + + $(OBJ) : g.h + %.o : %.c + $(CC) -c $(CFLAGS) -o $(@:f) $< + mv $(@:f) objdir + + .SOURCE.o : objdir # tell dmake to look here for .o's + + An example of building library members would go something like this: + (NOTE: The same rules as above will be used to produce .o's from .c's) + + SRC= a b + + + +Dmake Version 4.12 2008-02-26 48 + + + + + +DMAKE(1) DMAKE(1) + + + LIB= lib + LIBm= { $(SRC) }.o + + prgm: $(LIB) + cc -o $@ $(LIB) + + $(LIB) .LIBRARY : $(LIBm) + ar rv $@ $< + rm $< + + Finally, suppose that each of the source files in the previous example + had the `:' character in their target name. Then we would write the + above example as: + + SRC= f:a f:b + LIB= lib + LIBm= "{ $(SRC) }.o" # put quotes around each token + + prgm: $(LIB) + cc -o $@ $(LIB) + + $(LIB) .LIBRARY : $(LIBm) + ar rv $@ $< + rm $< + +COMPATIBILITY + There are two notable differences between dmake and the standard ver- + sion of BSD UNIX 4.2/4.3 Make. + + 1. BSD UNIX 4.2/4.3 Make supports wild card filename expansion + for prerequisite names. Thus if a directory contains a.h, + b.h and c.h, then a line like + + target: *.h + + will cause UNIX make to expand the *.h into "a.h b.h c.h". + dmake does not support this type of filename expansion. + + 2. Unlike UNIX make, touching a library member causes dmake to + search the library for the member name and to update the + library time stamp. This is only implemented in the UNIX + version. MSDOS and other versions may not have librarians + that keep file time stamps, as a result dmake touches the + library file itself, and prints a warning. + + dmake is not compatible with GNU Make. In particular it does not + understand GNU Make's macro expansions that query the file system. + + dmake is fully compatible with SYSV AUGMAKE, and supports the following + AUGMAKE features: + + 1. GNU Make style include, and if/else/endif directives are + allowed in non-group recipes. Thus, the word include appear- + ing at the start of a line that is not part of a gruop recipe + will be mapped to the ".INCLUDE" directive that damke uses. + Similarly, the words ifeq,ifneq,elif,else, and endif are + mapped to their corresponding dmake equivalents. + + 2. The macro modifier expression $(macro:str=sub) is understood + and is equivalent to the expression $(macro:s/str/sub), with + the restriction that str must match the following regular + expression: + + str[ |\t][ |\t]* + + + +Dmake Version 4.12 2008-02-26 49 + + + + + +DMAKE(1) DMAKE(1) + + + (ie. str only matches at the end of a token where str is a + suffix and is terminated by a space, a tab, or end of line) + Normally sub is expanded before the substitution is made, if + you specify -A on the command line then sub is not expanded. + + 3. The macro % is defined to be $@ (ie. $% expands to the same + value as $@). + + 4. The AUGMAKE notion of libraries is handled correctly. + + 5. Directories are always made if you specify -A. This is con- + sistent with other UNIX versions of Make. + + 6. Makefiles that utilize virtual targets to force making of + other targets work as expected if AUGMAKE special target han- + dling is enabled. For example: + + FRC: + myprog.o : myprog.c $(FRC) ; ... + + Works as expected if you issue the command + + 'dmake -A FRC=FRC' + + but fails with a 'don't know how to make FRC' error message + if you do not specify AUGMAKE special target handling via the + -A flag (or by setting AUGMAKE:=yes internally). + +LIMITS + In some environments the length of an argument string is restricted. + (e.g. MSDOS command line arguments cannot be longer than 128 bytes if + you are using the standard command.com command interpreter as your + shell, dmake text diversions may help in these situations.) + +PORTABILITY + To write makefiles that can be moved from one environment to another + requires some forethought. In particular you must define as macros all + those things that may be different in the new environment. dmake has + two facilities that help to support writing portable makefiles, recur- + sive macros and conditional expressions. The recursive macros, allow + one to define environment configurations that allow different environ- + ments for similar types of operating systems. For example the same + make script can be used for SYSV and BSD but with different macro defi- + nitions. + + To write a makefile that is portable between UNIX and MSDOS requires + both features since in almost all cases you will need to define new + recipes for making targets. The recipes will probably be quite differ- + ent since the capabilities of the tools on each machine are different. + Different macros will be needed to help handle the smaller differences + in the two environments. + +FILES + Makefile, makefile, startup.mk (use dmake -V to tell you where the + startup file is) + +SEE ALSO + sh(1), csh(1), touch(1), f77(1), pc(1), cc(1) + S.I. Feldman Make - A Program for Maintaining Computer Programs + +AUTHOR + Dennis Vadura, dvadura@wticorp.com + Many thanks to Carl Seger for his helpful suggestions, and to Trevor + John Thompson for his many excellent ideas and informative bug reports. + + + +Dmake Version 4.12 2008-02-26 50 + + + + + +DMAKE(1) DMAKE(1) + + + Many thanks also go to those on the NET that have helped in making + dmake one of the best Make tools available. + +BUGS + Some system commands return non-zero status inappropriately. Use -i + (`-' within the makefile) to overcome the difficulty. + + Some systems do not have easily accessible time stamps for library mem- + bers (MSDOS, AMIGA, etc) for these dmake uses the time stamp of the + library instead and prints a warning the first time it does so. This + is almost always ok, except when multiple makefiles update a single + library file. In these instances it is possible to miss an update if + one is not careful. + + This man page is way too long. + +WARNINGS + Rules supported by make(1) may not work if transitive closure is turned + off (-T, .NOINFER). + + PWD from csh/ksh will cause problems if a cd operation is performed and + -e or -E option is used. + + Using internal macros such as COMMAND, may wreak havoc if you don't + understand their functionality. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Dmake Version 4.12 2008-02-26 51 + + diff --git a/dmake/man/dmake.tf b/dmake/man/dmake.tf new file mode 100644 index 000000000000..981d82fc0609 --- /dev/null +++ b/dmake/man/dmake.tf @@ -0,0 +1,3480 @@ +.\" Copyright (c) 1990,...,1995 Dennis Vadura, All rights reserved. +.\" +.\" You must use groff to format this man page!!! +.\" +.ds TB "0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.2i +0.5i +0.5i +2.0i +.de Ip +.sp \\n[PD]u +.nf +.nr dmake-indent \w@\\$1 @u +.IP "\\$1" \\n[dmake-indent]u +\\$2 +.. +.de Is +.nr dmake-indent \w@\\$1@u +.nf +.. +.de Ii +.PD 0 +.IP "\\$1" \\n[dmake-indent]u +.it 1 PD +.. +.TH DMAKE 1 "2008-02-26" "Dmake Version 4.12" +.SH NAME +\fBdmake\fR \- maintain program groups, or interdependent files +.SH SYNOPSIS +.nh +.B dmake +[\-P#] [\-{f|C|K} file] [\-{w|W} target ...] +[macro[[!][*][+][:]]=\fIvalue\fP ...] +[\-ABcdeEghiknpqrsStTuVxX] [\-v[cdfimrtw]] [\-m[trae]] [target ...] +.hy 14 +.SH DESCRIPTION +.PP +.B dmake +is a re-implementation of the UNIX Make utility with significant enhancements. +.B dmake +executes commands found in an external file called a +.I makefile +to update one or more target names. +Each target may depend on zero or more prerequisite targets. +If any of the target's prerequisites is newer than the target or if the target +itself does not exist, then +.B dmake +will attempt to make the target. +.PP +If no +.B \-f +command line option is present then +.B dmake +searches for an existing +.I makefile +from the list of prerequisites specified for the special target \fI.MAKEFILES\fR +(see the STARTUP section for more details). +If "\-" is the name of the file specified to the +.B \-f +flag then \fBdmake\fR uses standard input as the source of the makefile text. +.PP +Any macro definitions (arguments with embedded "=" +signs) that appear on the command line are processed first +and supercede definitions for macros of the same name found +within the makefile. In general it is impossible for definitions found +inside the makefile to redefine a macro defined on the command line, see the +MACROS section for exceptions. +.PP +If no +.I target +names are specified on the command line, then \fBdmake\fR uses the first +non-special target found in the makefile as the default target. +See the +.B "SPECIAL TARGETS" +section for the list of special targets and their function. +Makefiles written for most previous +versions of +.I Make +will be handled correctly by +.B dmake. +Known differences between \fBdmake\fR and other versions of make +are discussed in the +.B COMPATIBILITY +section found at the end of this document. +.B dmake +returns 0 if no errors were detected and a non-zero result if an error +occurred. +.SH OPTIONS +.IP "\fB\-A\fR" +Enable AUGMAKE special inference rule transformations +(see the "PERCENT(%) RULES" and "AUGMAKE META RULES" sections), these are +set to off by default. +.IP "\fB\-B\fR" +Enable the use of spaces instead of <tabs> to begin recipe lines. +This flag equivalent to the .NOTABS special macro and is further described +below. +.IP "\fB\-c\fR" +Use non-standard comment stripping. If you specify \fB\-c\fP then +.B dmake +will treat any \fB#\fP character as a start of comment character wherever it +may appear unless it is escaped by a \e. +.IP "\fB\-C [+]file\fR" +This option writes to \fIfile\fP a copy of standard output and +standard error from any child processes and from the +.B dmake +process itself. If you specify a \fB+\fP prior to the file name then +the text is appended to the previous contents of \fIfile\fP. +This option is active in the MSDOS implementation only and is ignored +by non-MSDOS versions of +.B dmake. +.IP "\fB\-d\fR" +Disable the use of the directory cache. Normally \fBdmake\fP caches directories +as it checks file timestamps. Giving this flag is equivalent to the +\&.DIRCACHE attribute or macro being set to \fIno\fP. +.IP "\fB\-E\fR" +Read the environment and define all strings of the +form '\fBENV\-VAR\fP=\fIevalue\fP' +defined within as macros whose name is \fBENV\-VAR\fP, +and whose value is '\fIevalue\fP'. +The environment is processed prior to processing the user +specified makefile thereby allowing definitions in the makefile to override +definitions in the environment. +.IP "\fB\-e\fR" +Same as \-E, except that the environment is processed after the +user specified makefile has been processed +(thus definitions in the environment override definitions in the makefile). +The \-e and \-E options are mutually exclusive. +If both are given the latter takes effect. +.IP "\fB\-f file\fR" +Use \fBfile\fR as the source for the makefile text. +Only one \fB\-f\fR option is allowed. +.IP "\fB\-g\fR" +Globally disable group recipe parsing, equivalent to the .IGNOREGROUP +attribute or macro being set to \fIyes\fP at the start of the makefile. +.IP "\fB\-h\fR" +Print the command summary for \fBdmake\fR. +.IP "\fB\-i\fR" +Tells \fBdmake\fR to ignore errors, and continue making other targets. +This is equivalent to the .IGNORE attribute or macro. +.IP "\fB\-K file\fR" +Turns on \fB.KEEP_STATE\fP state tracking and tells \fBdmake\fP to use +\fIfile\fP as the state file. +.IP "\fB\-k\fR" +Causes \fBdmake\fR to ignore errors caused by command execution and to make +all targets not depending on targets that could not be made. +Ordinarily \fBdmake\fR stops after a command returns a non-zero status, +specifying \fB\-k\fR causes \fBdmake\fR to ignore the error +and continue to make as much as possible. +.IP "\fB\-m[trae]\fR" +Measure timing information. Print the time when targets and/or recipes +are started and finished to stdout. The following format is used: +.IP "" +\fB{s|e} {target|recipe} time maketarget\fP +.IP "" +\fBs\fP or \fBe\fP stands for started or ended, \fBtarget\fP or +\fBrecipe\fP denotes if this line refers to the whole target or a +recipe. \fBtime\fP is displayed in Unix time format, i.e. the number +of seconds since an epoch. (Since 1970-01-01T00:00:00Z). \fBmaketarget\fP +obviously represents the target the timing information is given for. +The optional flags \fB[trae]\fP can be used to change the information that +is displayed. If no optional flags are given only the \fBt\fP flag +is assumed to be selected, ie. \fB\-mt\fP. The optional flags stand for: +.RS +.IP "\fBt\fP" +Display the start and end time of each target. +.IP "\fBr\fP" +Display the start and end time of each recipe. +.IP "\fBa\fP" +Display the target as an absolute path, i.e. prepend the current working +directory. +.IP "\fBe\fP" +Also display the start and end time of the \fB$(shell command)\fP function +(aka. shell escape) macros. +.RE +.IP "\fB\-n\fR" +Causes \fBdmake\fR to print out what it would have executed, +but does not actually execute the commands. A special check is made for +the string "$(MAKE)" inside a recipe line, if it is found, +the line is expanded and invoked, thereby enabling recursive makes to give a +full description of all that they will do. +This check is disabled inside group recipes. +.IP "\fB\-p\fR" +Print out a version of the digested makefile in human readable form. +(useful for debugging, but cannot be re-read by \fBdmake\fP) +.IP "\fB\-P#\fR" +On systems that support multi-processing cause \fBdmake\fP to use \fI#\fP +concurrent child processes to make targets. +See the "MULTI PROCESSING" section for more information. +.IP "\fB\-q\fR" +Check and see if the target is up to date. Exits with code 0 if up to date, +1 otherwise. +.IP "\fB\-r\fR" +Tells \fBdmake\fR not to read the initial startup makefile, see STARTUP +section for more details. +.IP "\fB\-s\fR" +Tells \fBdmake\fR to do all its work silently and not echo the commands it is +executing to stdout (also suppresses warnings). +This is equivalent to the .SILENT attribute or macro. +.IP "\fB\-S\fR" +Force sequential execution of recipes on architectures which support +concurrent makes. For backward compatibility with old makefiles that have +nasty side-effect prerequisite dependencies. (Implies -P1) +.IP "\fB\-t\fR" +Causes \fBdmake\fR to touch the targets and bring them up to date +without executing any commands. +Note that targets will not be created if they do not already exist. +.IP "\fB\-T\fR" +Tells \fBdmake\fP to not perform transitive closure on the inference graph. +.IP "\fB\-u\fR" +Force an unconditional update. (ie. do everything that would +be done if everything that a target depended on was out of date) +.IP "\fB\-v[cdfimrtw]\fR" +Verbose flag, when making targets print to stdout what we are going to make +and what we think its time stamp is. The optional flags \fB[cdfimrtw]\fP can be +used to restrict the information that is displayed. In the absence of any +optional flags all are assumed to be given (ie. \fB\-v\fP is equivalent to +\fB\-vcdfimrtw\fP). The meanings of the optional flags are: +.RS +.IP "\fBc\fP" +Notify of directory cache operations only. +.IP "\fBd\fP" +Notify of change directory operations only. +.IP "\fBf\fP" +Notify of file I/O operations only. +.IP "\fBi\fP" +Notify of inference algorithm operation only. +.IP "\fBm\fP" +Notify of target update operations only. +.IP "\fBr\fP" +Force output of recipe lines, warnings and executed commands. This switch +is usefull when debugging makefiles that disable the output using the @ +or @@ property for recipe lines or the .SILENT target/attribute. +It also overrides the -s flag. +.IP "\fBt\fP" +Keep any temporary files created; normally they are automatically deleted. +.IP "\fBw\fP" +Notify of non-essential warnings (these are historical). +.RE +.IP "\fB\-V\fR" +Print the version of \fBdmake\fR, and values of builtin macros. +.IP "\fB\-W target\fR" +Run \fBdmake\fP pretending that \fItarget\fP is out of date. +.IP "\fB\-w target\fR" +\fIWhat if?\fP Show what would be made if \fItarget\fP were out of date. +.IP "\fB\-x\fR" +Upon processing the user makefile export all non-internally defined macros +to the user's environment. This option together with the \-e option +allows SYSV AUGMAKE recursive makes to function as expected. +.IP "\fB\-X\fR" +Inhibit the execution of \fB#!\fP lines found at the beginning of a makefile. +The use of this flag prevents non-termination of recursive make invocations. +.SH INDEX +Here is a list of the sections that follow and a short description of each. +Perhaps you won't have to read the entire man page to find +what you need. +.IP \fBSTARTUP\fP 1.9i +Describes \fBdmake\fP initialization. +.IP \fBSYNTAX\fP 1.9i +Describes the syntax of makefile expressions. +.IP \fBATTRIBUTES\fP 1.9i +Describes the notion of attributes and how they are used when +making targets. +.IP \fBMACROS\fP 1.9i +Defining and expanding macros. +.IP "\fBRULES AND TARGETS" 1.9i +How to define targets and their prerequisites. +.IP \fBRECIPES\fP 1.9i +How to tell \fBdmake\fP how to make a target. +.IP "\fBBUILTIN COMMANDS\fP" 1.9i +Internal dmake commands. +.IP "\fBTEXT DIVERSIONS\fP" 1.9i +How to use text diversions in recipes and macro expansions. +.IP "\fBVIRTUAL TARGETS\fP" 1.9i +Targets that only enforce dependencies, but which can not create a target file. +.IP "\fBSPECIAL TARGETS\fP" 1.9i +Some targets are special. +.IP "\fBSPECIAL MACROS\fP" 1.9i +Macros used by \fBdmake\fP to alter the processing of the makefile, +and those defined by \fBdmake\fP for the user. +.IP "\fBCONTROL MACROS\fP" 1.9i +Itemized list of special control macros. +.IP "\fBRUNTIME MACROS\fP" 1.9i +Discussion of special run-time macros such as $@ and $<. +.IP "\fBFUNCTION MACROS\fP" 1.9i +Description of functional macros. +.IP "\fBCONDITIONAL MACROS\fP" 1.9i +Target specific conditional macros. +.IP "\fBDYNAMIC PREREQUISITES\fP" 1.9i +Processing of prerequisites which contain macro expansions in their name. +.IP "\fBBINDING TARGETS\fP" 1.9i +The rules that \fBdmake\fP uses to bind +a target to an existing file in the file system. +.IP "\fBPERCENT(%) RULES\fP" 1.9i +Specification of recipes to be used by the inference algorithm. +.IP "\fBMAKING INFERENCES\fP" 1.9i +The rules that \fBdmake\fP uses when inferring how to make a target which +has no explicit recipe. This and the previous section are really a single +section in the text. +.IP "\fBAUGMAKE META RULES\fP" 1.9i +A subclass of the \fBPERCENT(%) RULES\fP. +.IP "\fBMAKING TARGETS\fP" 1.9i +How \fBdmake\fP makes targets other than libraries. +.IP "\fBMAKING LIBRARIES\fP" 1.9i +How \fBdmake\fP makes libraries. +.IP "\fBKEEP STATE\fP" 1.9i +A discussion of how .KEEP_STATE works. +.IP "\fBMULTI PROCESSING\fP" 1.9i +Discussion of \fBdmake's\fP parallel make facilities for architectures that +support them. +.IP "\fBCONDITIONALS\fP" 1.9i +Conditional expressions which control the processing of the makefile. +.IP "\fBEXAMPLES\fP" 1.9i +Some hopefully useful examples. +.IP "\fBCOMPATIBILITY\fP" 1.9i +How \fBdmake\fP compares with previous versions of make. +.IP "\fBLIMITS\fP" 1.9i +Limitations of \fBdmake\fP. +.IP \fBPORTABILITY\fP 1.9i +Comments on writing portable makefiles. +.IP \fBFILES\fP 1.9i +Files used by \fBdmake\fP. +.IP "\fBSEE ALSO\fP" 1.9i +Other related programs, and man pages. +.IP "\fBAUTHOR\fP" 1.9i +The guy responsible for this thing. +.IP \fBBUGS\fP 1.9i +Hope not. +.SH STARTUP +When +.B dmake +begins execution it first processes the command line and then processes +an initial startup-makefile. +This is followed by an attempt to locate and process a user supplied makefile. +The startup file defines the default values of all required control macros +and the set of default rules for making targets and inferences. +When searching for the startup makefile, +.B dmake +searches the following locations, in the order specified, +until a startup file is located: +.LP +.RS +.IP 1. +The location given as the value of the macro +MAKESTARTUP defined on the command line. +.IP 2. +The location given as the value of the environment variable MAKESTARTUP +defined in the current environment. +.IP 3. +The location given as the value of the macro +MAKESTARTUP defined internally within \fBdmake\fP. In this version, the +internal definition of MAKESTARTUP is "$(DMAKEROOT)/startup.mk", so you +can set the environment variable DMAKEROOT to the location of your startup +directory. +.sp +If DMAKEROOT is not changed, for native Windows dmake versions its value +defaults to "$(ABSMAKECMD:d)startup" (see definition of ABSMAKECMD for +details). +For unix like versions build with the autotools build system it defaults +to the value of "${prefix}/share/startup" at build time. The actual value, +usually something like /usr/local/share/startup can be checked with the \-V +command line switch. +.RE +.LP +The above search is disabled by specifying the \-r option on the command line. +An error is issued if a startup makefile cannot be found and the \-r +option was not specified. +A user may substitute a custom startup file by defining +the MAKESTARTUP environment variable or by redefining the +MAKESTARTUP macro on the command line. +To determine where +.B dmake +looks for the default startup file, check your environment or issue the command +\fI"dmake \-V"\fP. +.PP +A similar search is performed to locate a default user makefile when no +\fB\-f\fP command line option is specified. +By default, the prerequisite list of the special target .MAKEFILES +specifies the names of possible makefiles and the search order that +\fBdmake\fP should use to determine if one exists. +A typical definition for this target is: +.RS +.sp +\&.MAKEFILES : makefile.mk Makefile makefile +.sp +.RE +\fBdmake\fP will first look for makefile.mk and then the others. +If a prerequisite +cannot be found \fBdmake\fP will try to make it before going on to the next +prerequisite. For example, makefile.mk can be checked out of an RCS file +if the proper rules for doing so are defined in the startup file. +.PP +If the first line of the user makefile is of the form: +.RS +.sp +#!command command_args +.sp +.RE +then \fBdmake\fP will expand and run the command prior to reading any +additional input. If the return code of the command is zero then \fBdmake\fP +will continue on to process the remainder of the user makefile, if the return +code is non-zero then dmake will exit. +.PP +\fBdmake\fP builds the internal dependency graph as it parses a user specified +makefile. The graph is rooted at the special target \fB.ROOT\fP. .ROOT is the +top level target that dmake builds when it starts to build targets. All user +specified targets (those from the command line or taken as defaults from +the makefile) are made prerequisites of the special target \fB.TARGETS\fP. +\fBdmake\fP by default creates the relationship that .ROOT depends on .TARGETS +and as a result everything is made. This approach allows the user to customize, within +their makefile, the order and which, target, is built first. For example the +default makefiles come with settings for .ROOT that specify: +.sp +.RS +\&.ROOT .PHONY .NOSTATE .SEQUENTIAL : .INIT .TARGETS .DONE +.RE +.sp +with .INIT and .DONE defined as: +.sp +.RS +\&.INIT .DONE .PHONY:; +.RE +.sp +which nicely emulates the behaviour of Sun's make extensions. The building of +\&.ROOT's prerequisites is always forced to be sequential. However, this +definition is trivially changed by supplying the definition: +.sp +.RS +\&.ROOT : .TARGETS +.RE +.sp +which skips the preamble and postamble phases of building .TARGETS. +.PP +.B Please note +that even though .INIT and .DONE are special exceptions, see section SPECIAL +TARGETS, the use of self defined targets starting with `.' should be avoided +as they would be handled as .<suffix> meta targets. The target names _INIT +and _DONE for example would work equally well without the .<suffix> +drawback. +.SH SYNTAX +This section is a summary of the syntax of makefile statements. +The description is given in a style similar to BNF, where { } enclose +items that may appear zero or more times, and [ ] enclose items that +are optional. Alternative productions for a left hand side are indicated +by '\(->', and newlines are significant. All symbols in \fBbold\fP type +are text or names representing text supplied by the user. +.sp 2 +.RS +.Ip "Makefile" "\(-> { Statement }" +.Ip "Statement" "\(-> Macro-Definition" +\(-> Conditional-Macro-Definition +\(-> Conditional +\(-> Rule-Definition +\(-> Attribute-Definition +.Ip "Macro-Definition" "\(-> \fBMACRO = LINE\fP" +\(-> \fBMACRO [\fB!\fR]*= LINE\fP +\(-> \fBMACRO [\fB!\fR]:= LINE\fP +\(-> \fBMACRO [\fB!\fR]*:= LINE\fP +\(-> \fBMACRO [\fB!\fR]+= LINE\fP +\(-> \fBMACRO [\fB!\fR]+:= LINE\fP +.Ip "Conditional-Macro-Definition \(-> " "\fBTARGET\fP ?= Macro-Definition" +.Ip "Conditional \(-> " "\fB\&.IF\fR expression" + Makefile +[ \fB.ELIF\fR expression + Makefile ] +[ \fB.ELSE\fR + Makefile ] +\fB\&.END\fR +.Ip "expression" "\(-> \fBLINE\fR" +\(-> \fBSTRING\fR +\(-> expression \fB==\fR expression +\(-> expression \fB!=\fR expression +\(-> expression \fB<=\fR expression +\(-> expression \fB>=\fR expression +\(-> \fB(\fR expression \fB)\fR +\(-> expression \fB||\fR expression +\(-> expression \fB&&\fR expression +.Ip "Rule-Definition \(-> " "target-definition" + [ recipe ] +.PP +target-definition \(-> targets [attrs] op { \fBPREREQUISITE\fP } [\fB;\fR rcp-line] +.Ip "targets" "\(-> target { targets }" +\(-> \fB"\fRtarget\fB"\fR { targets } +.Ip "target" "\(-> special-target" +\(-> \fBTARGET\fR +.Ip "attrs" "\(-> attribute { attrs }" +\(-> \fB"\fRattribute\fB"\fR { attrs } +.Ip "op" "\(-> \fB:\fR { modifier }" +.Ip "modifier" "\(-> \fB:\fR" +\(-> \fB^\fR +\(-> \fB!\fR +\(-> \fB\-\fR +\(-> \fB|\fR +.Ip "recipe" "\(-> { \fBTAB\fR rcp-line }" +\(-> [\fB@\fR[\fB@\fR]][\fB%\fR][\fB\-\fR] \fB[ +.Is "recipe \(-> " +.Ii " " + \fR{ \fBLINE\fR } +.Ii " " +\fB]\fR +.Ip "rcp-line" "\(-> [\fB@\fR[\fB@\fR]][\fB%\fR][\fB\-\fR][\fB+\fR] \fBLINE\fR" +.Ip Attribute-Definition "\(-> attrs \fB:\fR targets" +.Ip attribute "\(-> \fB.EPILOG\fR" +\(-> \fB.ERRREMOVE\fR +\(-> \fB.EXECUTE\fR +\(-> \fB.GROUP\fR +\(-> \fB.IGNORE\fR +\(-> \fB.IGNOREGROUP\fR +\(-> \fB.LIBRARY\fR +\(-> \fB.MKSARGS\fR +\(-> \fB.NOINFER\fR +\(-> \fB.NOSTATE\fR +\(-> \fB.PHONY\fR +\(-> \fB.PRECIOUS\fR +\(-> \fB.PROLOG\fR +\(-> \fB.SETDIR=\fIpath\fP\fR +\(-> \fB.SILENT\fR +\(-> \fB.SEQUENTIAL\fR +\(-> \fB.SWAP\fR +\(-> \fB.USESHELL\fR +\(-> \fB.SYMBOL\fR +\(-> \fB.UPDATEALL\fR +\(-> \fB.WINPATH\fR +.Ip "special-target" "\(-> \fB.ERROR\fR" +\(-> \fB.EXIT\fR +\(-> \fB.EXPORT\fR +\(-> \fB.GROUPEPILOG\fR +\(-> \fB.GROUPPROLOG\fR +\(-> \fB.IMPORT\fR +\(-> \fB.INCLUDE\fR +\(-> \fB.INCLUDEDIRS\fR +\(-> \fB.MAKEFILES\fR +\(-> \fB.REMOVE\fR +\(-> \fB.ROOT\fR +\(-> \fB.SOURCE\fR +\(-> \fB.SOURCE.\fIsuffix\fR +\(-> \fB.SUFFIXES (deprecated)\fR +\(-> \fB.TARGETS\fR +\(-> \fB.INIT\fR +\(-> \fB.DONE\fR +\(-> .\fIsuffix\fR +\(-> .\fIsuffix1\fR.\fIsuffix2\fR +.fi +.RE +.sp 1 +.PP +Where, \fBTAB\fP represents a <tab> character, \fBSTRING\fP represents an +arbitrary sequence of characters, and +\fBLINE\fP represents a +possibly empty sequence of characters terminated by a non-escaped +(not immediately preceded by a backslash '\e') new-line character. +\fBMACRO\fP, \fBPREREQUISITE\fP, +and \fBTARGET\fP each represent a string of characters not +including space or tab which respectively form the name of a macro, +prerequisite or target. +The name may itself be a macro expansion expression. +A \fBLINE\fP can be continued over several physical lines by terminating it with +a single backslash character. Comments are initiated by the +pound \fB#\fR character and extend to the end of line. +All comment text is discarded, a '#' may be placed into the makefile text +by escaping it with '\e' (ie. \e# translates to # when it is parsed). +An exception to this occurs when a # is seen inside +a recipe line that begins with a <tab> or is inside a group recipe. +If you specify the \fB\-c\fP command line switch then this behavior is +disabled and +.B dmake +will treat all # characters as start of comment indicators unless they +are escaped by \e. +A set of continued lines may be commented out by placing a single # at the +start of the first line. +A continued line cannot span more than one makefile. +.PP +\fBwhite space\fP is defined to be any combination of +<space>, <tab>, and the sequence \e<nl> when \e<nl> is used to terminate a +LINE. \fBNote\fP the special treatment of \e<nl> in macro definion and recipe +lines below. +When processing \fBmacro definition\fP lines, +any amount of white space is allowed on either side of the macro operator +and white space is stripped from both before and after the macro +value string. A \e<nl> sequence in a macro definition is deleted from the +macro value before assigning this value. +During \fBrecipe expansion\fP the sequence \e<nl> is treated as white space +but is deleted from the final recipe string. +You must escape the \e<nl> with another \e in order to get a \e at the end +of a recipe or macro definition line. +.PP +When processing \fBtarget\fP definition lines, +the recipe for a target must, in general, follow the first definition +of the target (See the RULES AND TARGETS section for an exception), and +the recipe may not span across multiple makefiles. +Any targets and prerequisites found on a target definition line are taken +to be white space separated tokens. +The rule operator (\fIop\fP in SYNTAX section) is also considered +to be a token but does not require +white space to precede or follow it. Since the rule operator begins with a `:', +traditional versions of make do not allow the `:' character to +form a valid target name. \fBdmake\fP allows `:' to be present in +target/prerequisite names as long as the entire target/prerequisite name is +quoted. For example: +.sp +\ta:fred : test +.sp +would be parsed as TARGET = a, PREREQUISITES={fred, :, test}, which +is not what was intended. To fix this you must write: +.sp +\t"a:fred" : test +.sp +Which will be parsed as expected. Quoted target and prerequisite +specifications may also contain white space thereby allowing the use of +complex function macro expressions.. +See the EXAMPLES section for how to apply \fB"\fP quoting +to a list of targets. +.SH ATTRIBUTES +.B dmake +defines several target attributes. Attributes may be +assigned to a single target, a group of targets, or to all targets in the +makefile. Attributes are used to modify +\fBdmake\fP actions during target update. +The recognized attributes are: +.sp +.IP \fB.EPILOG\fP 1.2i +Insert shell epilog code when executing a group recipe associated with +any target having this attribute set. +.IP \fB.ERRREMOVE\fP 1.2i +Always remove any target having this attribute if an error is encountered +while making them. Setting this attribute overrides the .PRECIOUS attribute. +.IP \fB.EXECUTE\fP 1.2i +If the \-n flag was given then execute the recipe associated with any +target having this attribute set. +.IP \fB.FIRST\fP 1.2i +Used in conjunction with .INCLUDE. Terminates the inclusion with the first +successfully included prerequisite. +.IP \fB.GROUP\fP 1.2i +Force execution of a target's recipe as a group recipe. +.IP \fB.IGNORE\fP 1.2i +Ignore an error when trying to make any target with this attribute set. +.IP \fB.IGNOREGROUP\fP 1.2i +Disable the special meaning of '[' to initiate a group recipe. +.IP \fB.LIBRARY\fP 1.2i +Target is a library. +.IP \fB.MKSARGS\fP 1.2i +If running in an MSDOS environment then use MKS extended argument passing +conventions to pass arguments to commands. Non-MSDOS +environments ignore this attribute. +.IP \fB.NOINFER\fP 1.2i +Any target with this attribute set will not be subjected +to transitive closure if it is inferred as a prerequisite +of a target whose recipe and prerequisites are being inferred. +(i.e. the inference algorithm will not use any prerequisite with this attribute +set, as a target) +If specified as '.NOINFER:' (ie. with no prerequisites or targets) then the +effect is equivalent to specifying \fB\-T\fP on the command line. +.IP \fB.NOSTATE\fP 1.2i +Any target with this attribute set will not have command line flag +information stored in the state file if .KEEP_STATE has been enabled. +.IP \fB.PHONY\fP 1.2i +Any target with this attribute set will have its recipe executed +each time the target is made even if a file matching the target name can +be located. Any targets that have a .PHONY attributed target as a +prerequisite will be made each time the .PHONY attributed prerequisite is +made. +.IP \fB.PRECIOUS\fP 1.2i +Do not remove associated target under any circumstances. +Set by default for any targets whose corresponding files exist in the file +system prior to the execution of \fBdmake\fP. +.IP \fB.PROLOG\fP 1.2i +Insert shell prolog code when executing a group recipe associated with +any target having this attribute set. +.IP \fB.SEQUENTIAL\fP 1.2i +Force a sequential make of the associated target's prerequisites. If set +as a global attribute this implies setting MAXPROCESS=1. +.IP \fB.SETDIR\fP 1.2i +Change current working directory to specified directory when making the +associated target. You must +specify the directory at the time the attribute is specified. To do this +simply give \fI.SETDIR=path\fP as the attribute. \fIpath\fP is expanded and +the result is used as the value of the directory to change to. +If \fIpath\fP contains \fB$$@\fP then the name of the target to be built is +used in computing the path to change directory to. +If path is surrounded by single quotes then path is not expanded, and is used +literally as the directory name. +If the \fIpath\fP contains any `:' characters then the entire attribute string +must be quoted using ". +If a target having this attribute set also has the .IGNORE +attribute set then if the change to the specified directory fails it will be +ignored, and no error message will be issued. +.IP \fB.SILENT\fP 1.2i +Do not echo the recipe lines when making any target with this attribute set, +and do not issue any warnings. +.IP \fB.SWAP\fP 1.2i +Under MSDOS +when making a target with this attribute set swap the \fBdmake\fP executable +to disk prior to executing the recipe line. Also see the '%' recipe line +flag defined in the RECIPES section. +.IP \fB.SYMBOL\fP 1.2i +Target is a library member and is an entry point into a module in the +library. This attribute is used only when searching a library for a target. +Targets of the form lib((entry)) have this attribute set automatically. +.IP \fB.USESHELL\fP 1.2i +Force each recipe line of a target to be executed using a shell. +Specifying this attribute is equivalent to specifying the '+' character at the +start of each line of a non-group recipe. +.IP \fB.UPDATEALL\fP 1.2i +Indicates that all the targets listed in this rule are updated by the +execution of the accompanying recipe. +A common example is the production of the +.I y.tab.c +and +.I y.tab.h +files by +.B yacc +when it is run on a grammar. Specifying .UPDATEALL in such a rule +prevents the running of yacc twice, once for the y.tab.c file and once +for the y.tab.h file. .UPDATEALL targets that are specified in a single rule +are treated as a single target and all timestamps are updated whenever any +target in the set is made. As a side-effect, \fBdmake\fP internally sorts +such targets in ascending alphabetical order and the value of $@ is always +the first target in the sorted set. +.IP \fB.WINPATH\fP 1.2i +Switch between default (POSIX) and Windows style path representation. +(This attribute is specific for cygwin dmake executables and non-cygwin +environments ignore this attribute.) +.sp +Under Cygwin it can be useful to generate Windows style paths (with +regular slashes) instead of the default cygwin style (POSIX) paths +for dmake's dynamic macros. +The affected macros are $@, $*, $>, $?, $<, $&, $^ and $(MAKEDIR), $(PWD), +$(TMD), $(TMPFILE) and the $(mktmp ...) function macro. +This feature can be used to create DOS style path parameters +for native W32 programs from dynamic macros. +.sp +\fBNote\fP that the Windows style paths use regular slashes ('/') instead +of the usual Windows backslash ('\\') as directory separator to avoid quoting +problems (after all it is still a cygwin \fBdmake\fP!) and cygwin, as well +as native Windows, programs should have no problems using this (c:/foo/bar) +path representation. +.sp +Example: Assuming the current target to be /tmp/mytarget the $@ macro +without .WINPATH active expands to: +.RS +.sp +.RS +/tmp/mytarget +.sp +.RE +With .WINPATH set it expands to: +.sp +.RS +C:/cygwin/tmp/mytarget +.RE +.RE +.LP +All attributes are user setable and except for .UPDATEALL and .MKSARGS +may be used in one of two forms. +The .MKSARGS attribute is restricted to use as a global attribute, and +the use of the .UPDATEALL attribute is restricted to rules +of the second form only. +.sp +\tATTRIBUTE_LIST : \fItargets\fP +.sp +assigns the attributes specified by ATTRIBUTE_LIST to each target in +.I targets +or +.sp +\t\fItargets\fP ATTRIBUTE_LIST : ... +.sp +assigns the attributes specified by ATTRIBUTE_LIST to each target in +.I targets. +In the first form if +.I targets +is empty (ie. a NULL list), then the +list of attributes will apply to all targets in the makefile +(this is equivalent to the common Make construct of \fI".IGNORE :"\fP +but has been modified to the notion of an attribute instead of +a special target). +Not all of the attributes have global meaning. +In particular, .LIBRARY, .NOSTATE, .PHONY, .SETDIR, .SYMBOL and .UPDATEALL +have no assigned global meaning. +.PP +Any attribute may be used with any target, even with the special targets. +Some combinations are useless (e.g. .INCLUDE .PRECIOUS: ... ), +while others are useful (e.g. .INCLUDE .IGNORE : "file.mk" will not complain +if file.mk cannot be found using the include file search rules, +see the section on SPECIAL TARGETS for a description of .INCLUDE). +If a specified attribute will not be used with the special target a warning +is issued and the attribute is ignored. +.SH MACROS +.B dmake +supports six forms of macro assignment. +.sp +.IP "\fBMACRO = LINE\fP" 1.55i +This is the most common and familiar form of macro assignment. It assigns +LINE literally as the value of MACRO. +Future expansions of MACRO recursively expand its value. +.IP "\fBMACRO *= LINE\fP" 1.55i +This form behaves exactly as the simple '=' form with the exception that if +MACRO already has a value then the assignment is not performed. +.IP "\fBMACRO := LINE\fP" 1.55i +This form differs from the simple '=' form in that it expands LINE +prior to assigning it as the value of MACRO. +Future expansions of MACRO do not recursively expand its value. +.IP "\fBMACRO *:= LINE\fP" 1.55i +This form behaves exactly as the ':=' form with the exception that if +MACRO already has a value then the assignment and expansion are not performed. +.IP "\fBMACRO += LINE\fP" 1.55i +This form of macro assignment allows macro values to grow. It takes the +literal value of LINE and appends it to the previous value of MACRO separating +the two by a single space. +Future expansions of MACRO recursively expand its value. +.IP "\fBMACRO +:= LINE\fP" 1.55i +This form is similar to the '+=' form except that the value of LINE is expanded +prior to being added to the value of MACRO. +.PP +Macro expressions specified on the command line allow the macro value +to be redefined within the makefile only if the macro is defined using +the '+=' and '+:=' operators. Other operators will define a macro that cannot +be further modified. +.PP +Each of the preceeding macro assignment operators may be prefixed by \fB!\fP +to indicate that the assignment should be forced and that no warnings should +be issued. Thus, specifying \fB!\fP has the effect of silently forcing the +specified macro assignment. +.PP +When \fBdmake\fP defines a non-environment macro it strips leading and +trailing white space from the macro value. +Macros imported from the environment via either the .IMPORT special +target (see the SPECIAL TARGETS section), or the \fB\-e\fP, or \fB\-E\fP flags +are an exception to this rule. Their values are +always taken literally and white space is never stripped. +In addition, named macros defined using the .IMPORT special target do +not have their values expanded when they are used within a makefile. +In contrast, environment macros that are imported +due to the specification of the \fB\-e\fP or \fB\-E\fP flags +are subject to expansion when used. +.PP +To specify a macro expansion +enclose the name in () or {} and precede it with a dollar sign $. +Thus $(TEST) represents an expansion of the macro variable named TEST. +If TEST is +defined then $(TEST) is replaced by its expanded value. If TEST is not +defined then $(TEST) expands to the NULL string (this is equivalent to +defining a macro as 'TEST=' ). A short form may be used for single character +named macros. In this case the parentheses are optional, and $(I) is +equivalent to $I. +Macro expansion is recursive, hence, if the value string contains an expression +representing a macro expansion, the expansion is performed. Circular macro +expansions are detected and cause an error to be issued. +.PP +When defining a macro the given macro name is first expanded before being used +to define the macro. Thus it is possible to define macros whose names +depend on values of other macros. For example, suppose CWD is defined as +.sp +\tCWD = $(PWD:b) +.sp +then the value of $(CWD) is the name of the current directory. +This can be used to define macros specific to this directory, for +example: +.sp +\t_$(CWD).prt = list of files to print... +.sp +The actual name of the defined macro is a function of the current directory. +A construct such as this is useful when processing a hierarchy of directories +using .SETDIR attributed targets and a collection of small distributed +makefile stubs. +.PP +Macro variables may be defined within the makefile, on the command +line, or imported from the environment. +.PP +.B \fBdmake\fR +supports several non-standard macro expansions: +The first is of the form: +.RS +.IP \fI$(macro_name:modifier_list:modifier_list:...)\fR +.RE +.LP +where +.I modifier_list +may be a combination of: +.RS +.sp +.Is "b or B " +.Ii "b or B" +\- file (not including suffix) portion of path names +.Ii "d or D" +\- directory portion of all path names +.Ii "e or E" +\- suffix portion of path names +.Ii "f or F" +\- file (including suffix) portion of path names +.Ii "i or I" +\- inferred names of targets +.Ii "n or N" +\- normalized path names +.Ii "l or L" +\- macro value in lower case +.Ii "u or U" +\- macro value in upper case +.Ii "1" +\- return the first white space separated token from value +.RE +.sp +or a single one of: +.RS +.sp +.Ii "m or M" +\- map escape codes found in macro to their ASCII value +.Ii "s or S" +\- simple pattern substitution +.Ii "t or T" +\- tokenization. +.Ii "^" +\- prepend a prefix to each token +.Ii "+" +\- append a suffix to each token +.sp +.RE +.fi +Thus if we have the example: +.RS +test = d1/d2/d3/a.out f.out d1/k.out +.RE +The following macro expansions produce the values on the right of '\(->' after +expansion. +.RS +.sp +.Is "$(test:s/out/in/:f) " +.Ii "$(test:d)" +\(-> d1/d2/d3/ d1/ +.Ii "$(test:b)" +\(-> a f k +.Ii "$(test:f)" +\(-> a.out f.out k.out +.Ii "${test:db}" +\(-> d1/d2/d3/a f d1/k +.Ii "${test:s/out/in/:f}" +\(-> a.in f.in k.in +.Ii $(test:f:t"+") +\(-> a.out+f.out+k.out +.Ii $(test:e) +\(-> .out .out .out +.Ii $(test:u) +\(-> D1/D2/D3/A.OUT F.OUT D1/K.OUT +.Ii $(test:1) +\(-> d1/d2/d3/a.out +.RE +.fi +.PP +For this macro +.RS +test = d1/d2/../a.out "d1/file name.ext" +.RE +the following results are returned: +.RS +.sp +.Is "$(test:s/out/in/:f) " +.Ii "$(test:n)" +\(-> d1/a.out "d1/file name.ext" +.RE +.fi +.PP +If a token ends in a string composed from the value of the macro DIRBRKSTR +(ie. ends in a directory separator string, e.g. '/' in UNIX) and you use the +\fB:d\fP modifier then the expansion returns the directory name less the +final directory separator string. Thus successive pairs of :d modifiers +each remove a level of directory in the token string. +.PP +The infered names of targets \fB:i\fP modifier returnes the actual filename +associated to the target, see BINDING TARGETS. If the value is not a target or +prerequisite the value is returned unchanged. For the following example: +.RS +test = aprog bprog +.RE +If aprog and bprog are targets or prerequisits and they are bound +to /tmp/aprog and bprog (see .SOURCE special target) the macro expansion +has the following effect: +.RS +.sp +.Is "$(test:s/out/in/:f) " +.Ii "$(test:i)" +\(-> /tmp/aprog bprog +.RE +.fi +.PP +The normalized path names \fB:n\fP modifier honors the setting of .WINPATH to +determine the output format of the result. +.PP +The map escape codes modifier changes the following escape codes \ea => <bel>, +\&\eb => <backspace>, \ef => <formfeed>, \en => <nl>, \er => <cr>, +\&\et => <tab>, \ev => <vertical tab>, \e" => ", and \exxx => <xxx> where +xxx is the octal representation of a character into the corresponding ASCII +value. +.PP +The tokenization, prepend and append modifier may use the same escape codes +that are supported by the map escape codes modifier in the string that is +inserted, prepended or added by the respective macro modifier. +These modifiers may quote this string to include otherwise problematic +characters. E.g. spaces, colons and parentheses. +.PP +The tokenization modifier takes all white space separated tokens from the +macro value and separates them by the separator string. Thus the +expansion: +.LP +.RS +.nf +$(test:f:t"+\en") +.RE +produces: +.RS +a.out+ +f.out+ +k.out +.fi +.RE +.PP +The prefix operator \fB^\fP takes all white space separated tokens from the +macro value and prepends \fIstring\fP to each. +.LP +.RS +.nf +$(test:f:^mydir/) +.RE +produces: +.RS +mydir/a.out mydir/f.out mydir/k.out +.fi +.RE +.PP +The suffix operator \fB+\fP takes all white space separated tokens from the +macro value and appends \fIstring\fP to each. +.LP +.RS +.nf +$(test:b:+.c) +.RE +produces: +.RS +a.c f.c k.c +.fi +.RE +.PP +The next non-standard form of macro expansion allows for recursive macros. +It is possible to specify a $(\fImacro_name\fR) or ${\fImacro_name\fR} expansion +where \fImacro_name\fR contains more $( ... ) or ${ ... } macro expansions +itself. +.PP +For example $(CC$(_HOST)$(_COMPILER)) will first expand CC$(_HOST)$(_COMPILER) +to get a result and use that result as the name of the macro to expand. +This is useful for writing a makefile for more than one target +environment. As an example consider the following hypothetical case. +Suppose that _HOST and _COMPILER are imported from the environment +and are set to represent the host machine type and the host compiler +respectively. +.RS +.sp +.nf +CFLAGS_VAX_CC = \-c \-O # _HOST == "_VAX", _COMPILER == "_CC" +CFLAGS_PC_MSC = \-c \-ML # _HOST == "_PC", _COMPILER == "_MSC" +.sp +# redefine CFLAGS macro as: +.sp +CFLAGS := $(CFLAGS$(_HOST)$(_COMPILER)) +.fi +.sp +.RE +This causes CFLAGS to take on a value that corresponds to the +environment in which the make is being invoked. +.PP +The final non-standard macro expansion is of the form: +.RS +.sp +string1{token_list}string2 +.RE +.LP +where string1, string2 and token_list are expanded. After expansion, +string1 is prepended to each token found in token_list and +string2 is appended to each resulting token from the previous prepend. +string1 and string2 are not delimited by white space +whereas the tokens in token_list are. +A null token in the token list +is specified using "". +Thus using another example we have: +.RS +.sp +.Is "test/{f1 f2}.o " +.Ii "test/{f1 f2}.o" +--> test/f1.o test/f2.o +.Ii "test/ {f1 f2}.o" +--> test/ f1.o f2.o +.Ii "test/{f1 f2} .o" +--> test/f1 test/f2 .o +.Ii "test/{""f1"" """"}.o" +--> test/f1.o test/.o +.sp +.Ii and +.sp +.Is "test/{d1 d2}/{f1 f2}.o --> " +.Ii "test/{d1 d2}/{f1 f2}.o --> " +test/d1/f1.o test/d1/f2.o +test/d2/f1.o test/d2/f2.o +.sp +.RE +.fi +This last expansion is activated only when the first characters of +\fItoken_list\fP +appear immediately after the opening '{' with no intervening white space. +The reason for this restriction is the following incompatibility with +Bourne Shell recipes. The line +.RS +.sp +{ echo hello;} +.sp +.RE +is valid /bin/sh syntax; while +.RS +.sp +{echo hello;} +.sp +.RE +.fi +is not. Hence the latter triggers the enhanced macro expansion while the former +causes it to be suppressed. +See the SPECIAL MACROS section for a description of the special macros that +\fBdmake\fP defines and understands. +.SH "RULES AND TARGETS" +A makefile contains a series of entries that specify dependencies. +Such entries are called \fItarget/prerequisite\fP or \fIrule\fP definitions. +Each rule definition +is optionally followed by a set of lines that provide a recipe for updating +any targets defined by the rule. +Whenever +.B dmake +attempts to bring a target up to date and an explicit recipe is provided with +a rule defining the target, that recipe is used to update the +target. A rule definition begins with a line having the following syntax: +.sp +.RS +.nf +\fI<targets>\fP [\fI<attributes>\fP] \fI<ruleop>\fP [\fI<prerequisites>\fP] [;\fI<recipe>\fP] +.fi +.RE +.sp +.I targets +is a non-empty list of targets. If the target is a +special target (see SPECIAL TARGETS section below) then it must appear alone +on the rule line. For example: +.sp +.RS +\&.IMPORT .ERROR : ... +.RE +.sp +is not allowed since both .IMPORT and .ERROR are special targets. +Special targets are not used in the construction of the dependency graph and +will not be made. +.PP +.I attributes +is a possibly empty list of attributes. Any attribute defined in the +ATTRIBUTES section above may be specified. All attributes will be applied to +the list of named targets in the rule definition. No other targets will +be affected. +.sp +.IP NOTE: 0.75i +As stated earlier, +if both the target list and prerequisite list are empty but the attributes +list is not, then the specified attributes affect all targets in the makefile. +.sp +.PP +.I ruleop +is a separator which is used to identify the targets from the prerequisites. +Optionally it also provides a facility for modifying the way in which +.B dmake +handles the making of the associated targets. +In its simplest form the operator is a single ':', and need not be separated +by white space from its neighboring tokens. It may additionally be followed +by any of the modifiers { !, ^, \-, :, | }, where: +.sp +.IP \fB!\fP +says execute the recipe for the associated targets once for each out of date +prerequisite. (The meaning of the runtime macro \fB$?\fP is changed, see +below in the +.B "RUNTIME MACROS" +section.) Ordinarily the recipe is executed +once for all out of date prerequisites at the same time. +.IP \fB^\fP +says to insert the specified prerequisites, if any, before any +other prerequisites already associated with the specified targets. +In general, it is not useful to specify ^ with an empty +list of prerequisites. +.IP \fB\-\fP +says to clear the previous list of prerequisites before adding +the new prerequisites. Thus, +.sp +\tfoo : +.br +\tfoo : bar baz +.sp +can be replaced by +.sp +\tfoo :\- bar baz +.sp +however the old form still works as expected. +.IP \fB:\fP +When the rule operator is not modified by a second ':' +only one set of rules may be specified for making a target. +Multiple definitions may be used to add to the +list of prerequisites that a target depends on. +However, if a target is multiply defined +only one definition may specify a recipe +for making the target. +.sp +When a target's rule operator is modified by a second ':' +(:: for example) then this definition may not be the only +definition with a recipe for the target. There may be other :: target +definition lines that specify a different set of prerequisites with a +different recipe for updating the target. +Any such target is made if any of the definitions +find it to be out of date +with respect to the related prerequisites +and the corresponding recipe is used to update the +target. By definition all '::' recipes that are found to be out of date for +are executed. +.sp +In the following simple example, each rule has a `::' \fIruleop\fP. In such an +operator we call the first `:' the operator, and the second `:' the modifier. +.sp +.nf +a.o :: a.c b.h + first recipe for making a.o + +a.o :: a.y b.h + second recipe for making a.o +.fi +.sp +If a.o is found to be out of date with respect to a.c then the first recipe +is used to make a.o. If it is found out of date with respect to a.y then +the second recipe is used. If a.o is out of date with respect to +b.h then both recipes are invoked to make a.o. +In the last case the order of invocation corresponds to the order in which the +rule definitions appear in the makefile. +.IP \fB|\fP +Is defined only for PERCENT rule target definitions. When specified it +indicates that the following construct should be parsed using the old +semantinc meaning: +.sp +.nf +%.o :| %.c %.r %.f ; some rule +.sp +is equivalent to: +.sp +%.o : %.c ; some rule +%.o : %.r ; some rule +%.o : %.f ; some rule +.fi +.PP +Targets defined using a single `:' operator +with a recipe may be redefined again with a new recipe by using a +`:' operator with a `:' modifier. +This is equivalent to a target having been +initially defined with a rule using a `:' modifier. +Once a target is defined using a `:' +modifier it may not be defined again with a recipe using only the `:' operator +with no `:' modifier. In both cases the use of a `:' modifier creates a new +list of prerequisites and makes it the current prerequisite list for the target. +The `:' operator with no recipe always modifies the current list +of prerequisites. +Thus assuming each of the following definitions has a recipe attached, then: +.RS +.sp +.nf +joe : fred ... (1) +joe :: more ... (2) +.sp +and +.sp +joe :: fred ... (3) +joe :: more ... (4) +.sp +.fi +.RE +are legal and mean: add the recipe associated with (2), or (4) to the set +of recipes for joe, placing them after existing recipes for +making joe. +The constructs: +.RS +.sp +.nf +joe :: fred ... (5) +joe : more ... (6) +.sp +and +.sp +joe : fred ... (7) +joe : more ... (8) +.sp +.fi +.RE +are errors since we have two sets of perfectly good recipes for +making the target. +.PP +.I prerequisites +is a possibly empty list of targets that must be brought up to date before +making the current target. +.PP +.I recipe +is a short form and allows the user to specify short rule definitions +on a single line. +It is taken to be the first recipe line in a larger recipe +if additional lines follow the rule definition. +If the semi-colon is present but the recipe line is empty (ie. null string) +then it is taken +to be an empty rule. Any target so defined causes target to be treated +as a virtual target, see VIRTUAL TARGETS below. +.SH "RECIPES" +The traditional format used by most versions of Make defines the recipe +lines as arbitrary strings that may contain macro expansions. They +follow a rule definition line and may be spaced +apart by comment or blank lines. +The list of recipe lines defining the recipe is terminated by a new target +definition, a macro definition, or end-of-file. +Each recipe line +.B MUST +begin with a \fB<TAB>\fP character (or \fBspaces\fP, see \fB.NOTABS\fP) +which may optionally be followed with one or all the following +.I recipe property +characters +.IR "'@%+\-'" +which affect the recipe execution: +.IP "'\-'" +indicates that non-zero exit values (ie. errors) +are to be ignored when this recipe line is executed. +.IP "'\+'" +indicates that the current recipe line is to be executed using the shell. Group recipes implicitely ignore this property. +.IP "'%'" +indicates that +.B dmake +should swap itself out to secondary storage (MSDOS only) before running the +recipe. +.IP "'@'" +indicates that the recipe line should NOT be echoed to the terminal prior to +being executed. +.IP "'@@'" +is a stronger version of the previous property. The recipe line and the +output (stdout and stderr) of the executed recipe are NOT shown on the +terminal. +.LP +Each property is off by default +(ie. by default, errors are significant, commands are echoed, no swapping is +done and a shell is +used only if the recipe line contains a character found in the value of the +SHELLMETAS macro). +Global settings activated via command line options or special attribute or +target names may also affect these settings. +An example recipe: +.sp +.RS +.nf +target : +.RS +first recipe line +second recipe line, executed independent of first. +@a recipe line that is not echoed +-and one that has errors ignored +%and one that causes dmake to swap out ++and one that is executed using a shell. +.RE +.fi +.RE +.PP +The second and new format of the recipe block begins the block with the +character '[' (the open group character) in the last non-white space +position of a line, and terminates the +block with the character ']' (the close group character) +in the first non-white space position of a line. +In this form each recipe line need not have a leading TAB. This is +called a recipe group. Groups so defined are fed intact as a single +unit to a shell for execution whenever the corresponding target needs to +be updated. If the open group character '[' is preceded +by one or all of the +.I recipe properties +(\-, %, @ and @@) +then they apply to the entire group in the same way that they +apply to single recipe lines. You may also specify '+' but it is +redundant as a shell is already being used to run the recipe. +See the MAKING TARGETS section for a description of how +.B dmake +invokes recipes. +Here is an example of a group recipe: +.sp +.RS +.nf +target : +[ + first recipe line + second recipe line + tall of these recipe lines are fed to a + single copy of a shell for execution. +] +.fi +.RE +.sp +.SH "BUILTIN COMMANDS" +.B dmake +supports some builtin commands. An optional leading '+' describes that +the builtin can be used also when being executed in a shell otherwise it +is only implemented when used directly. Remember that if a character of the +recipe is found in the SHELLMETAS macro the execution of the recipe in a +shell is forced. +.IP "[\fB+\fP]\fBnoop\fP [\fBsomething\fP]" +The \fBnoop\fP internal command always returns success if used but it is +not executed even though the rest of the commandline is evaluated. +This command can be used to evaluate macro expansions at the runtime of the +recipe without starting a real commmand. +.IP "[\fB+\fP]<empty recipe> +If an empty recipe line is encountered it is not executed. This sounds +more trivial than it really is because the recipe could consist of +macros that evaluated to empty or whitespace only strings. +.IP "\fBecho\fP [\fB-n\fP] \fBdata\fP" +This internal command prints data (with all leading whitespace removed, but +otherwise literally) to stdout. If the '-n' switch is given no trailing +newline is printed. Note that no quoting is removed nor that escape sequences +are handled. +.PP +No special treatment of buildin commands for group recipes is implemented +even though the <empty recipe> will most propably also not be evaluated by +most shells that can be used to handle the recipe groups. +.SH "TEXT DIVERSIONS" +.B dmake +supports the notion of text diversions. +If a recipe line contains the macro expression +.RS +.sp +$(mktmp[,[\fIfile\fP][,\fItext\fP]] \fIdata\fP) +.sp +.RE +then all text contained in the \fIdata\fP expression is expanded and +is written to a temporary file. The \fIdata\fP in the file will always +be terminated from a new line character. The \fIfile\fP parameter can +be used to override the name of the temporary file. If its expanded value +is not empty it will be used instead of the unique and thread safe file +name that otherwise would be generated internally. The return +value of the macro is the name of the temporary file unless the \fItext\fP +parameter is defined. In this case the return value is the expanded value +of \fItext\fP. +.PP +.I data +can be any text and must be separated from the 'mktmp' portion of the +macro name by white-space. The only restriction on the data text is that +it must contain a balanced number of parentheses of the same kind as are +used to initiate the $(mktmp ...) expression. For example: +.RS +.sp +$(mktmp $(XXX)) +.sp +.RE +is legal and works as expected, but: +.RS +.sp +$(mktmp text (to dump to file) +.sp +.RE +is not legal. You can achieve what you wish by either defining a macro that +expands to '(' or by using {} in the macro expression; like this: +.RS +.sp +${mktmp text (to dump to file} +.sp +.RE +Since the temporary file is opened when the +macro containing the text diversion expression is expanded, diversions may +be nested and any diversions that are created as part of ':=' macro +expansions persist for the duration of the +.B dmake +run. +If the \fIdata\fP text is to contain new lines the map escape codes macro +expasion can be used. For example the expression: +.RS +.sp +.nf +mytext:=this is a\entest of the text diversion +all: + cat $(mktmp $(mytext:m)) +.fi +.sp +.RE +is replaced by: +.RS +.sp +cat /tmp/mk12294AA +.sp +.RE +where the temporary file contains two lines both of which are terminated +by a new-line. +A second more illustrative example generates a response file to an MSDOS +link command: +.RS +.sp +.nf +OBJ = fred.obj mary.obj joe.obj +all : $(OBJ) + link @$(mktmp $(^:t"+\en")) +.fi +.sp +.RE +The result of making `all' in the second example is the command: +.RS +.sp +link @/tmp/mk02394AA +.sp +.RE +where the temporary file contains: +.RS +.sp +.nf +fred.obj+ +mary.obj+ +joe.obj +.fi +.sp +.RE +The last line of the file is terminated by a new-line which is always +inserted at the end of the \fIdata\fP string. +.PP +If the optional \fIfile\fP specifier is present it can be used to specify +the name of the temporary file to create. An example that would be useful +for MSDOS users with a Turbo-C compiler +.RS +.sp +$(mktmp,turboc.cfg $(CFLAGS)) +.sp +.RE +will place the contents of CFLAGS into a local \fIturboc.cfg\fP file. +The second optional argument, \fItext\fP, if present alters the name +of the value returned by the $(mktmp ...) macro. +.PP +Under MS-DOS text diversions may be a problem. Many DOS tools require +that path names which contain directories use the \e character to delimit +the directories. Some users however wish to use the '/' to delimit pathnames +and use environments that allow them to do so. +The macro USESHELL is set to "yes" if the +current recipe is forced to use a shell via the .USESHELL or '+' directives, +otherwise its value is "no". +The +.B dmake +startup files define the macro DIVFILE whose value is either the +value of TMPFILE or the value of TMPFILE edited to replace any '/' characters +to the appropriate value based on the current shell and whether it will be +used to execute the recipe. +.PP +Previous versions of +.B dmake +defined text diversions using <+, +> strings, +where <+ started a text diversion and +> terminated one. +.B dmake +is backward compatible with this construct only +if the <+ and +> appear literally +on the same recipe line or in the same macro value string. In such instances +the expression: +.sp +\t<+data+> +.sp +is mapped to: +.sp +\t$(mktmp data) +.sp +which is fully output compatible with the earlier construct. <+, +> +constructs whose text spans multiple lines must be converted by hand to use +$(mktmp ...). +.PP +If the environment variable TMPDIR is defined then the +temporary file is placed into the directory specified by that variable. +A makefile can modify the location of temporary files by +defining a macro named TMPDIR and exporting it using the .EXPORT special +target. +.SH "VIRTUAL TARGETS" +.B Dmake +allows to define targets with the sole purpose to enforce a dependency +chain that are unable to create the target, hence virtual targets. +When \fBdmake\fP tries to make a target, but only finds a target definition +without recipe lines, it would normally issues +a \fB"Don't know how to make ..."\fP error message, but if a target rule is +terminated by a semicolon and has no following recipe lines, +or if it has no recipe lines, but defines prerequisites, +or if the AUGMAKE mode is enabled (see the COMPATIBILITY section for details), +the target is treated as a virtual target and the error is suppressed. In +addition to this, if the default target does not have recipe lines it is also +treated as a virtual target. +.PP +Virtual targets should not have a corresponding file therefore +they inherit the time of their newest prerequisite if they have prerequisites, +otherwise they get the current time assigned when being made. +If the virtual target has a corresponding file a warning is issued, but the +time stamp of that file is taken into account. The virtual target uses the +time stamp of the corresponding file if it is newer than the one determined +by the previous rule. +.SH "SPECIAL TARGETS" +This section describes the special targets that are recognized by \fBdmake\fP. +Some are affected by attributes and others are not. +.IP \fB.ERROR\fP 1.4i +If defined then the recipe associated with this target is executed +whenever an error condition is detected by \fBdmake\fP. All attributes that +can be used with any other target may be used with this target. Any +prerequisites of this target will be brought up to date during its processing. +NOTE: errors will be ignored while making this target, in extreme cases this +may cause some problems. +.IP \fB.EXIT\fP 1.4i +If this target is encountered while parsing a makefile then the parsing of the +makefile is immediately terminated at that point. +.IP \fB.EXPORT\fP 1.4i +All prerequisites associated with this target are assumed to +correspond to macro names and they and their values +are exported to the environment as environment strings at the point in +the makefile at which this target appears. +Any attributes specified with this target are ignored. +Only macros which have been assigned a value in the makefile prior to the +export directive are exported, macros as yet undefined +or macros whose value contains any of the characters "+=:*" +are not exported. +.sp +Note that macros that are not expanded during the macro assignment and contain +other macros will be written into the environment containing these other +macros in the form of $(macroname). +.IP \fB.IMPORT\fP 1.4i +Prerequisite names specified for this target are searched for in the +environment and defined as macros with their value taken from the environment. +If the special name \fB.EVERYTHING\fP is used as a prerequisite name then +all environment variables defined in the environment are imported. +The functionality of the \fB\-E\fP flag can be forced by placing the construct +\&\fI.IMPORT : .EVERYTHING\fP at the start of a makefile. Similarly, by +placing the construct at the end, one can emulate the effect of the \fB\-e\fP +command line flag. +If a prerequisite name cannot be found in the environment +an error message is issued. +\&.IMPORT accepts the .IGNORE attribute. When given, it causes \fBdmake\fP +to ignore the above error. +See the MACROS section for a description of the processing of imported macro +values. +.IP \fB.INCLUDE\fP 1.4i +Parse another makefile just as if it had been located at the point of the +\&.INCLUDE in the current makefile. +The list of prerequisites gives the list of +makefiles to try to read. If the list contains multiple makefiles then they +are read in order from left to right. The following search rules are used +when trying to locate the file. If the filename is surrounded by " or just +by itself then it is searched for in the current directory. If it is not +found it is then searched for in each of the directories specified +as prerequisites of the \&.INCLUDEDIRS special target. +If the file name is surrounded by < and >, (ie. +<my_spiffy_new_makefile>) then it is searched for only in the directories +given by the .INCLUDEDIRS special target. In both cases if the file name is a +fully qualified name starting at the root of the file system then it is only +searched for once, and the .INCLUDEDIRS list is ignored. +If .INCLUDE fails to find the file it invokes the inference engine to +try to infer and hence make the file to be included. In this way the +file can be checked out of an RCS repository for example. +\&.INCLUDE accepts +the .IGNORE, .SETDIR, and .NOINFER attributes. +If the .IGNORE attribute is given and the file +cannot be found then \fBdmake\fP continues processing, +otherwise an error message is generated. +If the .NOINFER attribute is given and the file +cannot be found then \fBdmake\fP will not attempt to +\fIinfer and make\fP the file. +The .SETDIR attribute causes +.B dmake +to change directories to the specified directory prior to attempting the +include operation. If all fails \fBdmake\fP attempts to \fImake\fP the file +to be included. If making the file fails then \fBdmake\fP terminates unless +the .INCLUDE directive also specified the .IGNORE attribute. +If .FIRST is specified along with .INCLUDE then \fBdmake\fP attempts to +include each named prerequisite and will terminate the inclusion with the +first prerequisite that results in a successful inclusion. +.IP \fB.INCLUDEDIRS\fP 1.4i +The list of prerequisites specified for this target defines the set of +directories to search when trying to include a makefile. +.IP \fB.KEEP_STATE\fP 1.4i +This special target is a synonym for the macro definition +.sp +\&\t.KEEP_STATE := _state.mk +.sp +It's effect is to turn on STATE keeping and to define \fI_state.mk\fP +as the state file. +.IP \fB.MAKEFILES\fP 1.4i +The list of prerequisites is the set of files to try to read as the default +makefile. By default this target is defined as: +.sp +\t\&.MAKEFILES : makefile.mk Makefile makefile +.sp +.IP \fB.REMOVE\fP 1.4i +The recipe of this target is used whenever \fBdmake\fP needs to remove +intermediate targets that were made but do not need to be kept around. +Such targets result from the application of transitive closure on the +dependency graph. +.IP \fB.ROOT\fP 1.4i +The internal root of the dependency graph, see section STARTUP for details. +.IP \fB.SOURCE\fP 1.4i +The prerequisite list of this target defines a set of directories to check +when trying to locate a target file name. See the section on BINDING of +targets for more information. +.IP \fB.SOURCE.suff\fP 1.4i +The same as .SOURCE, except that the .SOURCE.suff list is searched first when +trying to locate a file matching the a target whose name ends in the suffix +\&.suff. +.IP \fB.SUFFIXES\fP 1.4i +This deprecated special target has no special meaning. Avoid its use. +.IP \fB.TARGETS\fP 1.4i +The internal targets that all user defined targets are prerequisites of, +see section STARTUP for details. +.PP +There are a few targets that are "slightly" special: +.RS +.nf + +\&\fB.INIT\fP +\&\fB.DONE\fP + +.fi +.RE +These targets exist because of historical reasons, see the usage of .INIT +and .DONE in section "STARTUP", they can be used and defined as ordinary +targets but are special in the sense that even though they start with a `.' +they are not treated as a .<suffix> meta target (See the AUGMAKE META RULES +section for details). +.PP +.B Please note +that self defined targets shouldn't use the prefix `.' as they would be +handled as .<suffix> meta targets and dmake most propably would complain +about this. +.PP +In addition to the special targets above, +several other forms of targets are recognized and are considered special, +their exact form and use is defined in the sections that follow. +.SH "SPECIAL MACROS" +.B dmake +defines a number of special macros. They are divided into three classes: +control macros, run-time macros, and function macros. +The control macros are used by +.B dmake +to configure its actions, and are the preferred method of doing so. +In the case when a control macro has the same function as a special +target or attribute they share the same name as the special target or +attribute. +The run-time macros are defined when +.B dmake +makes targets and may be used by the user inside recipes. +The function macros provide higher level functions dealing with macro +expansion and diversion file processing. +.SH "CONTROL MACROS" +To use the control macros simply assign them a value just like any other +macro. The control macros are divided into three groups: +string valued macros, character valued macros, and boolean valued macros. +.PP +The following are all of the string valued macros. +This list is divided into two groups. The first group gives the string +valued macros that are defined internally and cannot be directly set by the +user. +.IP \fBABSMAKECMD\fP 1.6i +\fBWarning!\fP This macro's value is differently defined for a native Windows +dmake executable (compiled with MS Visual C++ or MinGW) and dmake for other +operating systems or build with other compilers. +.sp +In the first case its value is the absolute filename of the executable of +the current dmake process, otherwise it is defined as the NULL string. +.IP \fBINCDEPTH\fP 1.6i +This macro's value is a string of digits representing +the current depth of makefile inclusion. +In the first makefile level this value is zero. +.IP \fBMFLAGS\fP 1.6i +Is the list of flags +that were given on the command line including a leading switch character. +The \-f flag is not included in this list. +.IP \fBMAKECMD\fP 1.6i +Is the name with which \fBdmake\fP was invoked. +.IP \fBMAKEDIR\fP 1.6i +Is the full path to the initial directory in which +.B dmake +was invoked. +.IP \fBMAKEFILE\fP 1.6i +Contains the string "\-f \fImakefile\fP" where, \fImakefile\fP is the name +of initial user makefile that was first read. +.IP \fBMAKEFLAGS\fP 1.6i +Is the same as $(MFLAGS) but has no leading switch +character. (ie. MFLAGS = \-$(MAKEFLAGS)) +.IP \fBMAKEMACROS\fP 1.6i +Contains the complete list of macro expressions that were specified on the +command line. +.IP \fBMAKETARGETS\fP 1.6i +Contains the name(s) of the target(s), if any, that were +specified on the command line. +.IP \fBMAKEVERSION\fP 1.6i +Contains a string indicating the current \fBdmake\fP version number. +.IP \fBMAXPROCESSLIMIT\fP 1.6i +Is a numeric string representing the maximum number of processes that +\fBdmake\fP can use when making targets using parallel mode. +.IP \fBNULL\fP 1.6i +Is permanently defined to be the NULL string. +This is useful when comparing a conditional expression to an NULL value. +.IP \fBPWD\fP 1.6i +Is the full path to the +current directory in which make is executing. +.IP \fBSPACECHAR\fP 1.6i +Is permanently defined to contain one space character. This is useful +when using space characters in function macros, e.g. subst, that +otherwise would get deleted (leading/trailing spaces) or for using +spaces in function macro parameters. +.IP \fBTMPFILE\fP 1.6i +Is set to the name of the most recent temporary file opened by \fBdmake\fP. +Temporary files are used for text diversions and for group recipe processing. +.IP \fBTMD\fP 1.6i +Stands for "To Make Dir", and +is the path from the present directory (value of $(PWD)) to the directory +that \fBdmake\fP was started up in (value of $(MAKEDIR)). If the present +directory is the directory that \fBdmake\fP was started up in TMD will be +set to the relative path ".". This allows to create valid paths by prepending +$(TMD)$(DIRSEPSTR) to a relative path. +This macro is modified when .SETDIR attributes are processed. +TMD will usually be a relative path with the following two exceptions. If the +relative path would go up until the root directory or if different drive +letters (DOS file system) make a relative path impossible the absolute path +from MAKEDIR is used. +.IP \fBUSESHELL\fP 1.6i +The value of this macro is set to "yes" if the current recipe is forced to +use a shell for its execution via the .USESHELL or '+' directives, its value +is "no" otherwise. +.sp +.PP +The second group of string valued macros control +.B dmake +behavior and may be set by the user. +.IP \fB.DIRCACHE\fP 1.6i +If set to "yes" enables the directory cache (this is the default). If set to +"no" disables the directory cache (equivalent to -d command-line flag). +.IP \fB.DIRCACHERESPCASE\fP 1.6i +If set to "yes" causes the directory cache, if enabled, to respect +file case, if set to "no" files are cached case insensitive. +By default it is set to "no" on Windows as the filesystems on +this operating system are case insensitive and set to "yes" for all +other operating systems. The default can be overriden, if desired. +.sp +\fBNote:\fP Using case insensitive directory caching on case sensitive +file systems is a \fBBAD\fP idea. If in doubt use case sensitive +directory caching even on case insensitive file systems as the +worst case in this scenario is that /foo/bar/ and /foo/BAR/ are +cached separately (with the same content) even though they are +the same directory. This would only happen if different targets +use different upper/lower case spellings for the same directory +and that is \fBnever\fP a good idea. +.IP \fBNAMEMAX\fP 1.6i +Defines the maximum length of a filename component. The value of the variable +is initialized at startup to the value of the compiled macro NAME_MAX. On +some systems the value of NAME_MAX is too short by default. Setting a new +value for NAMEMAX will override the compiled value. +.IP \fB.NOTABS\fP 1.6i +When set to "yes" enables the use of spaces as well as <tabs> to begin +recipe lines. +By default a non\-group recipe is terminated by a line without any leading +white\-space or by a line not beggining with a <tab> character. +Enabling this mode modifies the first condition of +the above termination rule to terminate a +non\-group recipe with a line that contains only white\-space. +This mode does not effect the parsing of group recipes bracketed by []. +.IP \fBAUGMAKE\fP 1.6i +If set to "yes" value will enable the transformation of special +meta targets to support special AUGMAKE inferences (See the "AUGMAKE +META RULES" and "COMPATIBILITY" sections). +.IP \fBDIRBRKSTR\fP 1.6i +Contains the string of chars used to terminate +the name of a directory in a pathname. +Under UNIX its value is "/", under MSDOS its value is "/\e:". +.IP \fBDIRSEPSTR\fP 1.6i +Contains the string that is used to separate directory components when +path names are constructed. It is defined with a default value at startup. +.IP \fBDIVFILE\fP 1.6i +Is defined in the startup file and gives the name that should be returned for +the diversion file name when used in +$(mktmp ...) expansions, see the TEXT DIVERSION section for details. +.IP \fB.KEEP_STATE\fP 1.6i +Assigning this macro a value tells +.B dmake +the name of the state file to use and turns on the keeping of state +information for any targets that are brought up to date by the make. +.IP \fBGROUPFLAGS\fP 1.6i +This macro gives the set of flags to pass to the shell when +invoking it to execute a group recipe. The value of the macro is the +list of flags with a leading switch indicator. (ie. `\-' under UNIX) +.IP \fBGROUPSHELL\fP 1.6i +This macro defines the full +path to the executable image to be used as the shell when +processing group recipes. This macro must be defined if group recipes are +used. It is assigned a default value in the startup makefile. Under UNIX +this value is /bin/sh. +.IP \fBGROUPSUFFIX\fP 1.6i +If defined, this macro gives the string to use as a suffix +when creating group recipe files to be handed to the command interpreter. +For example, if it is defined as .sh, then all +temporary files created by \fBdmake\fP will end in the suffix .sh. +Under MSDOS if you are using command.com as your GROUPSHELL, then this suffix +must be set to .bat in order for group recipes to function correctly. +The setting of GROUPSUFFIX and GROUPSHELL is done automatically for +command.com in the startup.mk files. +.IP \fBMAKE\fP 1.6i +Is defined in the startup file by default. +Initially this macro is defined to have the value "$(MAKECMD) $(MFLAGS)". +The string $(MAKE) is recognized when using the \-n switch. +.IP \fBMAKESTARTUP\fP 1.6i +This macro defines the full path to the initial startup +makefile. Use the \fB\-V\fP command line option to discover its initial +value. +.IP \fBMAXLINELENGTH\fP 1.6i +This macro defines the maximum size of a single line of +makefile input text. The size is specified as a number, the default value +is defined internally and is shown via the \fB\-V\fP option. +A buffer of this size plus 2 is allocated for reading makefile text. The +buffer is freed before any targets are made, thereby allowing files containing +long input lines to be processed without consuming memory during the actual +make. +This macro can only be used to extend the line length beyond it's default +minimum value. +.IP \fBMAXPROCESS\fP 1.6i +Specify the maximum number of child processes to use when making targets. +The default value of this macro is "1" and its value cannot exceed the value +of the macro MAXPROCESSLIMIT. Setting the value of MAXPROCESS on the command +line or in the makefile is equivalent to supplying a corresponding value to +the -P flag on the command line. If the global .SEQUENTIAL attribute is set +(or the -S command line switch is used) the value of MAXPROCESS is fixed +to "1" and cannot be changed. +.IP \fBOOODMAKEMODE\fP 1.6i +This macro enables a special compatibility mode needed by the OpenOffice.org +build system. If set, the switch disables the removal of leading './' path +elements during target filename normalization (See BINDING TARGETS). If './' +appear in the pathname, but not at the beginning of it, they are still +removed by the normalization. Please note that targets that are given on the +command line are going to be registered as default targets \fBafter\fP the +startup file is read. +.IP \fBPREP\fP 1.6i +This macro defines the number of iterations to be expanded +automatically when processing % rule definitions of the form: +.sp +% : %.suff +.sp +See the sections on PERCENT(%) RULES for details on how PREP is used. +.IP \fBSHELL\fP 1.6i +This macro defines the full path to the executable +image to be used as the shell when +processing single line recipes. This macro must be defined if recipes +requiring the shell for execution are to be used. +It is assigned a default value in the startup makefile. +Under UNIX this value is /bin/sh. +.IP \fBSHELLCMDQUOTE\fP 1.6i +This macro can be used to add additional characters before and after the +command string that is passed to the shell defined by the SHELL macro. +If needed, like for \fIcmd.exe\fP and \fIcommand.com\fP, it is assigned +a value in the startup file. +.IP \fBSHELLFLAGS\fP 1.6i +This macro gives the set of flags to pass to the shell when +invoking it to execute a single line recipe. The value of the macro is the +list of flags with a leading switch indicator. (ie. `\-' under UNIX) +.IP \fBSHELLMETAS\fP 1.6i +Each time +.B dmake +executes a single recipe line (not a group recipe) the line is +searched for any occurrence of a character defined in the value of SHELLMETAS. +If such a character is found the recipe line is defined to require a shell +to ensure its correct execution. In such instances +a shell is used to invoke the recipe line. +If no match is found the recipe line is executed without the use of a shell. +.sp +.PP +There is only one character valued macro defined by \fBdmake\fP: +\fBSWITCHAR\fP contains the switch character used +to introduce options on command lines. For UNIX its value is `\-', and for +MSDOS its value may be `/' or `\-'. +The macro is internally defined and is not user setable. +The MSDOS version of \fBdmake\fP attempts to first extract SWITCHAR from an +environment variable of the same name. If that fails it then attempts to +use the undocumented getswitchar system call, and returns the result of +that. Under MSDOS version 4.0 you must set the value of the environment +macro SWITCHAR to '/' to obtain predictable behavior. +.PP +All boolean macros currently understood by +.B dmake +correspond directly to the previously defined attributes. +These macros provide +a second way to apply global attributes, and represent the +preferred method of doing so. They are used by assigning them a +value. If the value is not a NULL string then the boolean condition +is set to on. +If the value is a NULL string then the condition is set to off. +There are five conditions defined and they correspond directly to the +attributes of the same name. Their meanings are defined in the ATTRIBUTES +section above. +The macros are: +\&\fB.EPILOG\fP, +\&\fB.IGNORE\fP, +\&\fB.MKSARGS\fP, +\&\fB.NOINFER\fP, +\&\fB.PRECIOUS\fP, +\&\fB.PROLOG\fP, +\&\fB.SEQUENTIAL\fP, +\&\fB.SILENT\fP, +\&\fB.SWAP\fP, and +\&\fB.USESHELL\fP. +Assigning any of these a non NULL value will globally set +the corresponding attribute to on. +.SH "RUNTIME MACROS" +These macros are defined +when \fBdmake\fP is making targets, and may take on different values for each +target. \fB$@\fP is defined to be the full target name, \fB$?\fP is the +list of all out of date prerequisites, except for the \fB!\fP ruleop, in +which case it is set to the current build +prerequisite instead. \fB$&\fP is the list of all +prerequisites, \fB$>\fP is the name of the library if the current target is a +library member, and +\fB$<\fP is the list of prerequisites specified in the current rule. +If the current target had a recipe inferred then \fB$<\fP is the name of the +inferred prerequisite even if the target had a list of prerequisites supplied +using an explicit rule that did not provide a recipe. In such situations +\fB$&\fP gives the full list of prerequisites. +.PP +\fB$*\fP is defined as +\fB$(@:db)\fP when making targets with explicit recipes and is defined as the +value of % when making targets whose recipe is the result of an inference. +In the first case \fB$*\fP is the target name with no suffix, +and in the second case, is the value of the matched % pattern from +the associated %-rule. +\fB$^\fP expands to the set of out of date prerequisites taken from the +current value of \fB$<\fP. +In addition to these, +\fB$$\fP expands to $, \fB{{\fP expands to {, \fB}}\fP expands to }, and the +strings \fB<+\fP and \fB+>\fP are recognized +as respectively starting and terminating a text diversion when they appear +literally together in the same input line. +.PP +The difference between $? and $^ can best be illustrated by an example, +consider: +.RS +.sp +.nf +fred.out : joe amy hello +\trules for making fred + +fred.out : my.c your.h his.h her.h # more prerequisites +.fi +.sp +.RE +Assume joe, amy, and my.c are newer then fred.out. When +.B dmake +executes the recipe for making fred.out the values of the following macros +will be: +.RS +.sp +.nf +.Is "$@ " +.Ii "$@" +--> fred.out +.Ii "$*" +--> fred +.Ii "$?" +--> joe amy my.c # note output of $? vs $^ +.Ii "$^" +--> joe amy +.Ii "$<" +--> joe amy hello +.Ii "$&" +--> joe amy hello my.c your.h his.h her.h +.fi +.sp +.RE +.SH "FUNCTION MACROS" +.B dmake +supports a full set of functional macros. One of these, the $(mktmp ...) +macro, is discussed in detail in the TEXT DIVERSION section and is not +covered here. +The names of function macros must appear literally after the opening $( +or ${. They are \fBnot\fP recognized if they are the result of a recursive +expansion. +.PP +Note that some of these macros take comma separated parameters +but that these parameters must not contain literal whitespaces. Whitespaces +in macros used in these parameters are allowed. +.RS +.sp +.IP "$(\fBand\fP \fBmacroterm ...\fP)" +expands each \fBmacroterm\fP in turn until there are no more or one of +them returns an empty string. If all expand to non-empty strings the +macro returs the string "t" otherwise it returns an empty string. +.sp +.IP "$(\fBassign\fP \fBexpression\fP)" +Causes \fIexpression\fP to be parsed as a macro assignment expression and results +in the specified assignment being made. An error is issued if the assignment +is not syntatically correct. \fIexpression\fP may contain white space. This is +in effect a dynamic macro assignment facility and may appear anywhere any +other macro may appear. The result of the expanding a dynamic macro +assignment expression is the name of the macro that was assigned and $(NULL) +if the \fIexpression\fP is not a valid macro assignment expression. +Some examples are: +.RS +.sp +.nf +$(assign foo := fred) +$(assign $(ind_macro_name) +:= $(morejunk)) +.fi +.RE +.IP "$(\fBecho\fP \fBlist\fP)" +Echo's the value of \fIlist\fP. \fIlist\fP is not expanded. +.IP "$(\fBeq\fP,\fItext_a\fP,\fItext_b\fP \fBtrue\fP \fBfalse\fP)" +expands +.I text_a +and +.I text_b +and compares their results. If equal it returns the result of the expansion +of the +.B true +term, otherwise it returns the expansion of the +.B false +term. +.IP "$(\fB!eq\fP,\fItext_a\fP,\fItext_b\fP \fBtrue\fP \fBfalse\fP)" +Behaves identically to the previous macro except that the +.B true +string is chosen if the expansions of the two strings are not equal +.IP "$(\fBforeach\fP,\fIvar\fP,\fIlist\fP \fBdata\fP)" +Implements iterative macro expansion over \fIdata\fP using \fBvar\fP as the +iterator taking on values from \fIlist\fP. \fIvar\fP and \fIlist\fP are +expanded and the result is the concatenation of expanding \fIdata\fP with +\fIvar\fP being set to each whitespace separated token from \fIlist\fP. +For example: +.RS +.RS +.sp +.nf +list = a b c +all :; echo [$(foreach,i,$(list) [$i])] +.fi +.sp +.RE +will output +.RS +.sp +.nf +[[a] [b] [c]] +.fi +.sp +.RE +The iterator variable is defined as a local variable to this foreach +instance. The following expression illustrates this: +.RS +.sp +.nf +$(foreach,i,$(foreach,i,$(sort c a b) root/$i) [$i/f.h]) +.fi +.sp +.RE +when evaluated the result is: +.RS +.sp +.nf +[root/a/f.h] [root/b/f.h] [root/c/f.h] +.fi +.sp +.RE +The specification of list must be a valid macro expression, such as: +.RS +.sp +.nf +$($(assign list=a b c)) +$(sort d a b c) +$(echo a b c) +.fi +.sp +.RE +and cannot just be the list itself. That is, the following foreach +expression: +.RS +.sp +.nf +$(foreach,i,a b c [$i]) +.fi +.sp +.RE +yields: +.RS +.sp +.nf +"b c [a]" +.fi +.sp +.RE +when evaluated. +.RE +.IP "$(\fBnil\fP \fBexpression\fP)" +Always returns the value of $(NULL) regardless of what \fIexpression\fP is. +This function macro can be used to discard results of expanding +macro expressions. +.IP "$(\fBnormpath\fP \fBlist\fP)" +Will return the normalized path names of all white-space separated tokens +in \fBlist\fP. Quotes can be used to normalize path names that contain +white-space characters. On cygwin the result honors the setting of .WINPATH +to determine the output format of the returned path names. +.IP "$(\fBnormpath,para\fP \fBlist\fP)" +Same as above except that the expanded value of \fBpara\fP is used to +override the .WINPATH setting. +.IP "$(\fBnot\fP \fBmacroterm\fP)" +expands \fBmacroterm\fP and returs the string "t" if the result of the +expansion is the empty string; otherwise, it returns the empty string. +.IP "$(\fBnull\fP,\fItext\fP \fBtrue\fP \fBfalse\fP)" +expands the value of +.I text. +If it is NULL then the macro returns the value of the expansion of \fBtrue\fP +and the expansion of \fBfalse\fP otherwise. The terms \fBtrue\fP, and +\fBfalse\fP must be strings containing no white\-space. +.IP "$(\fB!null\fP,\fItext\fP \fBtrue\fP \fBfalse\fP)" +Behaves identically to the previous macro except that the +.B true +string is chosen if the expansion of +.I text +is not NULL. +.IP "$(\fBor\fP \fBmacroterm ...\fP)" +expands each \fBmacroterm\fP in turn and returs the empty string if +each term expands to the empty string; otherwise, it returs the string +"t". +.IP "$(\fBshell\fP \fBcommand\fP)" +is a shell escape macro. It runs \fIcommand\fP as if it were part of a +recipe and returns, separated by a single space, all the non-white +space terms written to stdout by the command. +For example: +.RS +.RS +.sp +$(shell ls *.c) +.sp +.RE +will return \fI"a.c b.c c.c d.c"\fP if the files exist in the current +directory. The recipe modification flags \fB[+@%\-]\fP are honored if they +appear as the first characters in the command. For example: +.RS +.sp +$(shell +ls *.c) +.sp +.RE +will run the command using the current shell. +.LP +\fBNote\fP that if the macro is part of a recipe it will be evaluated after +all previous recipe lines have been executed. For obvious reasons it will be +evaluated before the current recipe line or group recipe is executed. +.RE +.IP "$(\fBshell,expand\fP \fBcommand\fP)" +Is an extension to the \fB$(shell command)\fP function macro that expands the +result of running \fBcommand\fP. +.IP "$(\fBsort\fP \fBlist\fP)" +Will take all white\-space separated tokens in \fIlist\fP and will +return their sorted equivalent list. +.IP "$(\fBstrip\fP \fBdata\fP)" +Will replace all strings of white\-space in data by a single space. +.IP "$(\fBsubst\fP,\fIpat\fP,\fIreplacement\fP \fBdata\fP)" +Will search for \fIpat\fP in +.B data +and will replace any occurrence of +.I pat +with the +.I replacement +string. The expansion +.RS +.sp +$(subst,.o,.c $(OBJECTS)) +.sp +.RE +is equivalent to: +.RS +.sp +$(OBJECTS:s/.o/.c/) +.sp +.RE +.IP "$(\fBuniq\fP \fBlist\fP)" +Will take all white\-space separated tokens in \fIlist\fP and will +return their sorted equivalent list containing no duplicates. +.sp +.RE +For historic reasons \fBdmake\fP treats the following case slightly special: +.RS +.sp +$(\fBname\fP \fBsomething\fP) +.sp +.RE +If it encounters a macro with a whitespace after \fBname\fP and \fBname\fP +is not literally one of the above mentioned function macro identifiers then +\fBdmake\fP will return the recursively expanded value of \fB$(name)\fP. +The remaining \fBsomething\fP part will be expanded but the result will be +discarded. The use of this special feature is deprecated and should not be +used. +.sp +.SH "CONDITIONAL MACROS" +.B dmake +supports conditional macros. These allow the definition of target specific +macro values. You can now say the following: +.RS +.sp +\fBtarget\fP ?= \fIMacroName MacroOp Value\fP +.sp +.RE +This creates a definition for \fIMacroName\fP whose value is \fIValue\fP +only when \fBtarget\fP is being made. You may use a conditional macro +assignment anywhere that a regular macro assignment may appear, including +as the value of a $(assign ...) macro. +.LP +The new definition is associated with the most recent cell definition +for \fBtarget\fP. If no prior definition exists then one is created. The +implications of this are immediately evident in the following example: +.sp +.RS +.nf +foo := hello +.sp +all : cond;@echo "all done, foo=[$(foo)] bar=[$(bar)]" +.sp +cond ?= bar := global decl +.sp +cond .SETDIR=unix::;@echo $(foo) $(bar) +cond ?= foo := hi +.sp +cond .SETDIR=msdos::;@echo $(foo) $(bar) + cond ?= foo := hihi +.fi +.RE +.sp +The first conditional assignment creates a binding for 'bar' that is +activated when 'cond' is made. The bindings following the :: definitions are +activated when their respective recipe rules are used. Thus the +first binding serves to provide a global value for 'bar' while any of the +cond :: rules are processed, and the local bindings for 'foo' come into +effect when their associated :: rule is processed. +.LP +Conditionals for targets of .UPDATEALL are all activated before the +target group is made. Assignments are processed in order. Note that +the value of a conditional macro assignment is NOT AVAILABLE until the +associated target is made, thus the construct +.sp +.RS +.nf +mytarget ?= bar := hello +mytarget ?= foo := $(bar) +.fi +.RE +.sp +results in $(foo) expanding to "", if you want the result to be "hello" +you must use: +.sp +.RS +.nf +mytarget ?= bar := hello +mytarget ?= foo = $(bar) +.fi +.RE +.sp +Once a target is made any associated conditional macros are deactivated +and their values are no longer available. Activation occurrs after all +inference, and .SETDIR directives have been processed and after $@ is +assigned, but before prerequisites are processed; thereby making the values of +conditional macro definitions available during construction of prerequisites. +.LP +If a %-meta rule target has associated conditional macro assignments, +and the rule is chosen by the inference algorithm then the conditional +macro assignments are inferred together with the associated recipe. +.SH "DYNAMIC PREREQUISITES" +.B dmake +looks for prerequisites whose names contain macro expansions during target +processing. Any such prerequisites are expanded and the result of the +expansion is used as the prerequisite name. As an example the line: +.sp +\tfred : $$@.c +.sp +causes the $$@ to be expanded when \fBdmake\fP is making fred, and it resolves +to the target \fIfred\fP. +This enables dynamic prerequisites to be generated. The value +of @ may be modified by any of the valid macro modifiers. So you can say for +example: +.sp +\tfred.out : $$(@:b).c +.sp +where the $$(@:b) expands to \fIfred\fP. +Note the use of $$ instead of $ to indicate the dynamic expansion, this +is due to the fact that the rule line is expanded when it is initially parsed, +and $$ then returns $ which later triggers the dynamic prerequisite expansion. +Dynamic macro expansion is performed in all user defined rules, and the special +targets .SOURCE*, and .INCLUDEDIRS. +.PP +\fBNOTE:\fP The use of a \fB$\fP as part of a prerequisite or target name is +\fBstrongly discouraged\fP as the runtime macros (like $@) are expanded when +used in a recipe line so that the $ is interpreted as a macro identifier and +not as a character of the filename leading to invalid runtime macros. +In addition to this no filename normalization is done for prerequisites and +targets that contain $ characters. +Nevertheless it is possible to use $ in prerequisites by using $$$$ but this +is \fBnot recommended\fP and can lead to surprising results. +.PP +If dynamic macro expansion results in multiple white space separated tokens +then these are inserted into the prerequisite list inplace of the dynamic +prerequisite. Due to the recursive nature of macro expansion the prerequisite +list is fully expanded even if the dynamic prerequisite contained other +runtime macros. +.SH "BINDING TARGETS" +This operation takes a target name and binds it to an existing file, if +possible. +.B dmake +makes a distinction between the internal target name of a target and its +associated external file name. +Thus it is possible for a target's internal name and its external +file name to differ. +To perform the binding, the following set of rules is used. +Assume that we are +trying to bind a target whose name is of the form \fIX.suff\fP, +where \fI.suff\fP is the suffix and \fIX\fP is the stem portion +(ie. that part which contains the directory and the basename). +.B dmake +takes this target name and performs a series of search operations that try to +find a suitably named file in the external file system. +The search operation is user controlled +via the settings of the various .SOURCE targets. +.RS +.IP 1. +If target has the .SYMBOL attribute set then look for it in the library. +If found, replace the target name with the library member name and continue +with step 2. If the name is not found then return. +.IP 2. +Extract the suffix portion (that following the `.') of the target name. +If the suffix is not null, look up the special target .SOURCE.<suff> +(<suff> is the suffix). +If the special target exists then search each directory given in +the .SOURCE.<suff> prerequisite list for the target. +If the target's suffix was null (ie. \fI.suff\fP was empty) then +perform the above search but use the special target .SOURCE.NULL instead. +If at any point a match is found then terminate the search. +If a directory in the prerequisite list is the special name `.NULL ' perform +a search for the full target name without prepending any directory portion +(ie. prepend the NULL directory). +.IP 3. +The search in step 2. failed. Repeat the same search but this time +use the special target .SOURCE. +(a default target of '.SOURCE : .NULL' is defined by \fBdmake\fP at startup, +and is user redefinable) +.IP 4. +The search in step 3. failed. +If the target has the library member attribute (.LIBMEMBER) +set then try to find the target in the library which was passed along +with the .LIBMEMBER attribute (see the MAKING LIBRARIES section). +The bound file name assigned to a target which is successfully +located in a library is the same name that would be assigned had the search +failed (see 5.). +.IP 5. +The search failed. Either the target was not found in any of the search +directories or no applicable .SOURCE special targets exist. +If applicable .SOURCE special targets exist, but the target was not found, +then \fBdmake\fP assigns the first name searched as the bound file name. +If no applicable .SOURCE special targets exist, +then the full original target name becomes the bound file name. +.RE +.PP +There is potential here for a lot of search operations. The trick is to +define .SOURCE.x special targets with short search lists and leave .SOURCE +as short as possible. +The search algorithm has the following useful side effect. +When a target having the .LIBMEMBER (library member) attribute is searched for, +it is first searched for as an ordinary file. +When a number of library members require updating it is desirable to compile +all of them first and to update the library at the end in a single operation. +If one of the members does not compile and \fBdmake\fP stops, then +the user may fix the error and make again. \fBdmake\fP will not remake any +of the targets whose object files have already been generated as long as +none of their prerequisite files have been modified as a result of the fix. +.PP +When \fBdmake\fP constructs target (and prerequisite) pathnames they are +normalized to the shortest (or most natural, see below for the cygwin case) +representation. Substrings like './' or of the form 'baz/..' are removed +and multiple slashes are collapsed to one unless they are at the beginning +of the pathname. Leading slashes are normalized according to POSIX rules, +i.e. more than two leading slashes are reduced to one slash and a +leading '//' is kept as it might have a special meaning. +For example "./foo", "bar/../foo" and foo are recognized as the same file. +This may result in somewhat unexpected values of the macro expansion +of runtime macros like \fB$@\fP, but is infact the corect result. +.PP +\fBNOTE:\fP A cygwin \fBdmake\fP executable will accept DOS like pathnames +with drive letters and cygwin POSIX pathnames and normalize them into its +natural POSIX representation. This might result in even more surprising +values of runtime macros. +.PP +When defining .SOURCE and .SOURCE.x targets the construct +.RS +.sp +\&.SOURCE : +.br +\&.SOURCE : fred gery +.sp +.RE +is equivalent to +.RS +.sp +\&.SOURCE :\- fred gery +.RE +.PP +\fBdmake\fP correctly handles the UNIX Make variable VPATH. By definition VPATH +contains a list of ':' separated directories to search when looking for a +target. \fBdmake\fP maps VPATH to the following special rule: +.RS +.sp +\&.SOURCE :^ $(VPATH:s/:/ /) +.sp +.RE +Which takes the value of VPATH and sets .SOURCE to the same set of directories +as specified in VPATH. +.SH "PERCENT(%) RULES AND MAKING INFERENCES" +When \fBdmake\fP makes a target, the target's set of prerequisites (if any) +must exist and the target must have a recipe which \fBdmake\fP +can use to make it. +If the makefile does not specify an explicit recipe for the target then +.B dmake +uses special rules to try to infer a recipe which it can use +to make the target. Previous versions of Make perform this task by using +rules that are defined by targets of the form .<suffix>.<suffix> (this is still +supported, see "AUGMAKE META RULES") or by using the \fBnot supported\fP by +dmake .SUFFIXES list of suffixes (see "SPECIAL TARGETS" for more details +about .SUFFIXES). The exact workings of this mechanism +were sometimes difficult to understand and often limiting in their usefulness. +Instead, \fBdmake\fP supports the concept of \fI%-meta\fP rules. +The syntax and semantics of these rules differ from standard rule lines as +follows: +.sp +.nf +.RS +\fI<%-targets>\fP [\fI<attributes>\fP] \fI<ruleop>\fP [\fI<%-prereqs>\fP] [;\fI<recipe>\fP] +.RE +.fi +.sp +where \fI%-targets\fP are one or more targets containing exactly a single `%' +sign, +.I attributes +is a list (possibly empty) of attributes, +.I ruleop +is the standard set of rule operators, +.I "%-prereqs" +\&, if present, is a list of prerequisites containing zero or more `%' signs, +and +.I recipe, +if present, is the first line of the recipe. +.PP +If more than one %-target is present this line is equivalent to a repetition +of the whole [<attributes>] <ruleop> [<%-prereqs>] [;<recipe>] sequence +for each %-target, i.e. it is possible to specify the same rule for multiple +%-targets. Because of this following only speaks about \fI<%-target>\fP as +\fI%-targets\fP are divided into multiple definitions with a single %-target. +.PP +\fBNOTE:\fP As multiple %-targets didn't work reliably with dmake versions prior +to 4.5 unless the rule operator `|:' was used we currently issue a warning +stating that it \fBnow\fP works. +.PP +The +.I %-target +defines a pattern against which a target whose recipe is +being inferred gets matched. The pattern match goes as follows: all chars are +matched exactly from left to right up to but not including the % sign in the +pattern, % then matches the longest string from the actual target name +not ending in +the suffix given after the % sign in the pattern. +Consider the following examples: +.RS +.sp +.nf +.Is "dir/%.c " +.Ii "%.c" +matches fred.c but not joe.c.Z +.Ii "dir/%.c" +matches dir/fred.c but not dd/fred.c +.Ii "fred/%" +matches fred/joe.c but not f/joe.c +.Ii "%" +matches anything +.fi +.sp +.RE +In each case the part of the target name that matched the % sign is retained +and is substituted for any % signs in the prerequisite list of the %-meta rule +when the rule is selected during inference and +.B dmake +constructs the new dependency. +.PP +.B Please note, +that only the first, non-indirect, prerequisite of the list is used for the +inference mechanism. If more than one non-indirect prerequisite is given +a warning is issued and all but the first non-indirect prerequisites are +ignored. See below for a description of indirect prerequisites. +.PP +As an example the following %-meta rules describe the following: +.RS +.sp +%.c : %.y ; recipe... +.sp +.RE +describes how to make any file ending in .c if a corresponding file ending +in .y can be found. +.RS +.sp +foo%.o : fee%.k ; recipe... +.sp +.RE +is used to describe how to make fooxxxx.o from feexxxx.k. +.RS +.sp +%.a :; recipe... +.sp +.RE +describes how to make a file whose suffix is .a without inferring any +prerequisites. +.RS +.sp +%.c : %.y 'yaccsrc/%.y' ; recipe... +.sp +.RE +matches the corresponding .y file as prerequisite and additionally another .y +file in the yaccsrc subdirectory as indirect prerequisite. +Another interesting example is: +.RS +.sp +% : RCS/%,v ; co $< +.sp +.RE +which describes how to take any target and check it out of +the RCS directory if the corresponding file exists in the RCS directory. +The equivalent SCCS rule would be: +.RS +.sp +% : s.% ; get $< +.sp +.RE +.PP +The previous RCS example defines an infinite rule, because it says how to make +.I anything +from RCS/%,v, and +.I anything +also includes RCS/fred.c,v. +To limit the size of the graph that results from such rules +.B dmake +uses the macro variable PREP (stands for % repetition). By default the value +of this variable is 0, which says that no repetitions of a %-rule are to be +generated. If it is set to something greater than 0, then that many +repetitions of any infinite %-rule are allowed. If in the above +example PREP was set to 1, then \fBdmake\fP would generate the dependency +graph: +.RS +.sp +% --> RCS/%,v --> RCS/RCS/%,v,v +.sp +.RE +Where each link is assigned the same recipe as the first link. +PREP should be used only in special cases, since it may result in +a large increase in the number of possible prerequisites tested. +.B dmake +further assumes that any target that has no suffix can be made from +a prerequisite that has at least one suffix. +.PP +.B dmake +supports dynamic prerequisite generation for prerequisites of %-meta rules. +This is best illustrated by an example. The RCS rule shown above can infer +how to check out a file from a corresponding RCS file only if the target +is a simple file name with no directory information. That is, the above rule +can infer how to find \fIRCS/fred.c,v\fP from the target \fIfred.c\fP, +but cannot infer how to find \fIsrcdir/RCS/fred.c,v\fP from \fIsrcdir/fred.c\fP +because the above rule will cause \fBdmake\fP to look for RCS/srcdir/fred.c,v; +which does not exist (assume that srcdir has its own RCS directory as is the +common case). +.PP +A more versatile formulation of the above RCS check out rule is the following: +.RS +.sp +% : $$(@:d)RCS/$$(@:f),v : co $@ +.sp +.RE +This rule uses the dynamic macro $@ to specify the prerequisite to try to +infer. During inference of this rule the macro $@ is set to the value of +the target of the %-meta rule and the appropriate prerequisite is generated by +extracting the directory portion of the target name (if any), appending the +string \fIRCS/\fP to it, and appending the target file name with a trailing +\fI,v\fP attached to the previous result. +.PP +.B dmake +can also infer indirect prerequisites. +An inferred target can have a list of prerequisites added that will not +show up in the value of $< but will show up in the value of $? and $&. +Indirect prerequisites are specified in an inference rule by quoting the +prerequisite with single quotes. For example, if you had the explicit +dependency: +.RS +.sp +.nf +fred.o : fred.c ; rule to make fred.o +fred.o : local.h +.fi +.sp +.RE +then this can be inferred for fred.o from the following inference rule: +.RS +.sp +%.o : %.c 'local.h' ; makes a .o from a .c +.sp +.RE +You may infer indirect prerequisites that are a function of the value of '%' +in the current rule. The meta-rule: +.RS +.sp +%.o : %.c '$(INC)/%.h' ; rule to make a .o from a .c +.sp +.RE +infers an indirect prerequisite found in the INC directory whose name is the +same as the expansion of $(INC), and the prerequisite name depends on the +base name of the current target. +The set of indirect prerequisites is attached to the meta rule in which they +are specified and are inferred only if the rule is used to infer a recipe +for a target. They do not play an active role in driving the inference +algorithm. +The construct: +.RS +.sp +%.o :| %.c %.f 'local.h'; recipe +.sp +.RE +is equivalent to: +.RS +.sp +.nf +%.o : %.c 'local.h' ; recipe +%.o : %.f 'local.h' ; recipe +.fi +.sp +.RE +.PP +If any of the attributes .EPILOG, .IGNORE, .LIBRARY, .NOSTATE, .PHONY, .PRECIOUS, +\&.PROLOG, .SETDIR, .SILENT, .SWAP, .USESHELL and .WINPATH +are given for a %-rule then when that rule is bound to a target +as the result of an inference, the target's set of attributes is augmented by +the attributes from the above set that are specified in the bound %-rule. +Other attributes specified for %-meta rules are not inherited by the target. +The .SETDIR attribute is treated in a special way. +If the target already had a .SETDIR attribute set then +.B dmake +changes to that directory prior to performing the inference. +During inference any .SETDIR attributes for the inferred prerequisite +are honored. +The directories must exist for a %-meta rule to be selected as a possible +inference path. If the directories do not exist no error message is issued, +instead the corresponding path in the inference graph is rejected. +.PP +.B dmake +bases all of its inferences on the inference graph constructed from the +%-rules defined in the makefile. +It knows exactly which targets can be made from which prerequisites by +making queries on the inference graph. +.PP +For a %-meta rule to be inferred as the +rule whose recipe will be used to make a target, the target's name must match +the %-target pattern, and any inferred %-prerequisite must already exist or +have an explicit recipe so that the prerequisite can be made. +Without \fItransitive closure\fP on the inference graph the above rule +describes precisely when an inference match terminates the search. +If transitive closure is enabled (the usual case), and a prerequisite does +not exist or cannot be made, then +.B dmake +invokes the inference algorithm recursively on the prerequisite to see if +there is some way the prerequisite can be manufactured. For, if the +prerequisite can be made then the current target can also be made using the +current %-meta rule. +This means that there is no longer a need to give a rule +for making a .o from a .y if you have already given a rule for making a .o +from a .c and a .c from a .y. In such cases +.B dmake +can infer how to make the +\&.o from the .y via the intermediary .c and will remove the .c when the .o is +made. Transitive closure can be disabled by giving the \-T switch on the +command line. +.PP +A word of caution. +.B dmake +bases its transitive closure on the %-meta rule targets. +When it performs transitive closure it infers how to make a target from a +prerequisite by performing a pattern match as if the potential prerequisite +were a new target. +The set of rules: +.RS +.nf +.sp +%.o : %.c ; rule for making .o from .c +%.c : %.y ; rule for making .c from .y +% : RCS/%,v ; check out of RCS file +.fi +.sp +.RE +will, by performing transitive closure, allow \fBdmake\fP to infer how to make +a .o from a .y using a .c as an intermediate temporary file. Additionally +it will be able to infer how to make a .y from an RCS file, as long as that +RCS file is in the RCS directory and has a name which ends in .y,v. +The transitivity computation is performed dynamically for each target that +does not have a recipe. This has potential to be costly if the %-meta +rules are not carefully specified. The .NOINFER attribute is used to mark +a %-meta node as being a final target during inference. Any node with this +attribute set will not be used for subsequent inferences. As an example +the node RCS/%,v is marked as a final node since we know that if the RCS file +does not exist there likely is no other way to make it. Thus the standard +startup makefile contains an entry similar to: +.RS +.nf +\&.NOINFER : RCS/%,v +.fi +.RE +Thereby indicating that the RCS file is the end of the inference chain. +Whenever the inference algorithm determines that a target can be made from +more than one prerequisite and the inference chains for the two methods +are the same length the algorithm reports an ambiguity and prints the +ambiguous inference chains. +.PP +.B dmake +tries to +remove intermediate files resulting from transitive closure if the file +is not marked as being PRECIOUS, or the \fB\-u\fP flag was not given on the +command line, and if the inferred intermediate did not previously exist. +Intermediate targets that existed prior to being made are never removed. +This is in keeping with the philosophy that +.B dmake +should never remove things from the file system that it did not add. +If the special target .REMOVE is defined and has a recipe then +.B dmake +constructs a list of the intermediate files to be removed and makes them +prerequisites of .REMOVE. It then makes .REMOVE thereby removing the +prerequisites if the recipe of .REMOVE says to. Typically .REMOVE is defined +in the startup file as: +.RS +.sp +\&.REMOVE :; $(RM) $< +.RE +.SH "AUGMAKE META RULES" +As a subclass of the meta targets that is actually mapped to %-meta rules +.B dmake +understands several SYSV AUGMAKE targets transformations. This .<suffix> +special target construct transforms into the following %-meta rules: +.RS +.sp +\&.suff :; recipe +.sp +.RE +gets mapped into: +.RS +.sp +% : %.suff; recipe +.sp +.RE +.PP +.B dmake +also supports the old format special target .<suffix>.<suffix> +by identifying any rules +of this form and mapping them to the appropriate %-rule. So for example if +an old makefile contains the construct: +.RS +.sp +\&.c.o :; cc \-c $< \-o $@ +.sp +.RE +.B dmake +maps this into the following %-rule: +.RS +.sp +%.o : %.c; cc \-c $< \-o $@ +.sp +.RE +The following SYSV AUGMAKE special targets transformation must be +enabled by providing the \-A flag +on the command line or by setting the value of AUGMAKE to non\-NULL. +The construct +.RS +.sp +\&.c~.o :; recipe +.sp +.RE +gets mapped into: +.RS +.sp +%.o : s.%.c ; recipe +.sp +.RE +In general, a special target of the form .<str>~ is replaced by the %-rule +construct s.%.<str>, thereby providing support for the syntax used by SYSV +AUGMAKE for providing SCCS support. +When enabled, these mappings allow processing of existing SYSV +makefiles without modifications. +.RE +.SH "MAKING TARGETS" +In order to update a target \fBdmake\fP must execute a recipe. +When a recipe needs to be executed it is first expanded so that any macros +in the recipe text are expanded, and it is then either executed directly or +passed to a shell. +.B dmake +supports two types of recipes. The regular recipes and group recipes. +.PP +When a regular recipe is invoked \fBdmake\fP executes each line of the recipe +separately using a new copy of a shell if a shell is required. +Thus effects of commands do not generally persist across recipe lines +(e.g. cd requests in a recipe line do not carry over to the next recipe line). +This is true even in environments such as \fBMSDOS\fP, where dmake internally +sets the current working director to match the directory it was in before +the command was executed. +.PP +The decision on whether a shell is required to execute a command is based on +the value of the macro SHELLMETAS or on the specification of '+' or .USESHELL +for the current recipe or target respectively. +If any character in the value of +SHELLMETAS is found in the expanded recipe text-line or the use of a shell +is requested explicitly via '+' or .USESHELL then the command is +executed using a shell, otherwise the command is executed directly. +The shell that is used for execution is given by the value of the macro SHELL. +The flags that are passed to the shell are given by the value of SHELLFLAGS. +Thus \fBdmake\fP constructs the command line: +.sp +\t$(SHELL) $(SHELLFLAGS) $(expanded_recipe_command) +.sp +If the $(SHELLCMDQUOTE) macro is set its value is inserted before and after +the $(expanded_recipe_command) string. +.sp +Normally +.B dmake +writes the command line that it is about to invoke to standard output. +If the .SILENT attribute is set for the target or for +the recipe line (via @), then the recipe line is not echoed. +.PP +Group recipe processing is similar to that of regular recipes, except that +a shell is always invoked. The shell that is invoked is given by the value of +the macro GROUPSHELL, and its flags are taken from the value of the macro +GROUPFLAGS. If a target has the .PROLOG attribute set then +.B dmake +prepends to the shell script the recipe associated with the special target +\&.GROUPPROLOG, and if the attribute .EPILOG is set as well, then the recipe +associated with the special target .GROUPEPILOG is appended to the script +file. +This facility can be used to always prepend a common header and common trailer +to group recipes. +Group recipes are echoed to standard output just like standard recipes, but +are enclosed by lines beginning with [ and ]. +.PP +The recipe flags [+,\-,%,@] are recognized at the start of a recipe line +even if they appear in a macro. For example: +.RS +.sp +.nf +SH = + +all: +\t$(SH)echo hi +.fi +.sp +.RE +is completely equivalent to writing +.RS +.sp +.nf +SH = + +all: +\t+echo hi +.fi +.sp +.RE +.PP +The last step performed by +.B dmake +prior to running a recipe is to set the macro CMNDNAME to the name of the +command to execute (determined by finding the first white\-space ending token +in the command line). It then sets the macro CMNDARGS to be the remainder +of the line. +.B dmake +then expands the macro COMMAND which by default is set to +.RS +.sp +COMMAND = $(CMNDNAME) $(CMNDARGS) +.sp +.RE +The result of this final expansion is the command that will be executed. +The reason for this expansion is to allow for a different interface to +the argument passing facilities (esp. under DOS) than that provided by +.B dmake\fR.\fP +You can for example define COMMAND to be +.RS +.sp +COMMAND = $(CMNDNAME) @$(mktmp $(CMNDARGS)) +.sp +.RE +which dumps the arguments into a temporary file and runs the command +.RS +.sp +$(CMNDNAME) @/tmp/ASAD23043 +.sp +.RE +which has a much shorter argument list. It is now up to the command to +use the supplied argument as the source for all other arguments. +As an optimization, if COMMAND is not defined +.B dmake +does not perform the above expansion. On systems, such as UNIX, that +handle long command lines this provides a slight saving in processing the +makefiles. +.SH "MAKING LIBRARIES" +Libraries are easy to maintain using \fBdmake\fP. A library is a file +containing a collection of object files. +Thus to make a library you simply specify it as a target with the .LIBRARY +attribute set and specify its list of prerequisites. The prerequisites should +be the object members that are to go into the library. When +.B dmake +makes the library target it uses the .LIBRARY attribute to pass to the +prerequisites the .LIBMEMBER attribute and the name of the library. This +enables the file binding mechanism to look for the member in the library if an +appropriate object file cannot be found. +.B dmake +now supports \fBElf\fP libraries on systems that support \fBElf\fP and +hence supports, on those systems, long member file names. +A small example best illustrates this. +.RS +.nf +.sp +mylib.a .LIBRARY : mem1.o mem2.o mem3.o +\trules for making library... +\t# remember to remove .o's when lib is made +.sp +# equivalent to: '%.o : %.c ; ...' +\&.c.o :; rules for making .o from .c say +.sp +.fi +.RE +.B dmake +will use the .c.o rule for making the library members if appropriate .c files +can be found using the search rules. NOTE: this is not specific in any way +to C programs, they are simply used as an example. +.PP +.B dmake +tries to handle the old library construct format in a sensible way. +The construct +.I lib(member.o) +is separated and the \fIlib\fP portion is declared +as a library target. +The new target is defined +with the .LIBRARY attribute set and the \fImember.o\fP portion of the +construct is +declared as a prerequisite of the lib target. +If the construct \fIlib(member.o)\fP +appears as a prerequisite of a target in the +makefile, that target has the new name of the lib assigned as its +prerequisite. Thus the following example: +.RS +.sp +.nf +a.out : ml.a(a.o) ml.a(b.o); $(CC) \-o $@ $< + +\&.c.o :; $(CC) \-c $(CFLAGS) \-o $@ $< +%.a: +.RS +ar rv $@ $? +ranlib $@ +rm \-rf $? +.RE +.sp +.fi +.RE +constructs the following dependency +graph. +.RS +.sp +.nf +a.out : ml.a; $(CC) \-o $@ $< +ml.a .LIBRARY : a.o b.o + +%.o : %.c ; $(CC) -c $(CFLAGS) \-o $@ $< +%.a : +.RS +ar rv $@ $? +ranlib $@ +rm -rf $? +.RE +.sp +.fi +.RE +and making a.out then works as expected. +.PP +The same thing happens for any target of the form \fIlib((entry))\fP. +These targets have an +additional feature in that the \fIentry\fP target has the .SYMBOL attribute +set automatically. +.PP +NOTE: If the notion of entry points is supported by the archive and by +\fBdmake\fP (currently not the case) then +.B dmake +will search the archive for the entry point and return not only the +modification time of the member which defines the entry but also the name of +the member file. This name will then replace \fIentry\fP and will be used for +making the member file. Once bound to an archive member the .SYMBOL +attribute is removed from the target. +This feature is presently disabled as there is little standardization +among archive formats, and we have yet to find a makefile utilizing this +feature (possibly due to the fact that it is unimplemented in most versions +of UNIX Make). +.PP +Finally, when +.B dmake +looks for a library member it must first locate the library file. +It does so by first looking for the library relative to the current directory +and if it is not found it then looks relative to the current value of +$(TMD). This allows commonly used libraries to be kept near the root of +a source tree and to be easily found by +.B dmake\fR.\fP +.SH "KEEP STATE" +.B dmake +supports the keeping of state information for targets that it makes whenever +the macro .KEEP_STATE is assigned a value. The value of the macro should be +the name of a state file that will contain the state information. If state +keeping is enabled then each target that does not poses the .NOSTATE +attribute will have a record written into the state file indicating the +target's name, the current directory, the command used to update the target, +and which, if any, :: rule is being used. When you make this target again +if any of this information does not match the previous settings and the +target is not out dated it will still be re\-made. The assumption is that one +of the conditions above has changed and that we wish to remake the target. +For example, +state keeping is used in the maintenance of +.B dmake +to test compile different versions of the source using different compilers. +Changing the compiler causes the compilation flags to be modified and hence +all sources to be recompiled. +.PP +The state file is an ascii file and is portable, however it is +not in human readable form as the entries represent hash keys of the above +information. +.PP +The Sun Microsystem's Make construct +.RS +.sp +\&.KEEP_STATE : +.sp +.RE +is recognized and is mapped to \fB.KEEP_STATE:=_state.mk\fP. +The +.B dmake +version of state keeping does not include scanning C source files for +dependencies like Sun Make. This is specific to C programs and it was +felt that it does not belong in make. +.B dmake +instead provides the tool, \fBcdepend\fP, to scan C source files and to produce +depedency information. Users are free to modify cdepend to produce other +dependency files. (NOTE: +.B cdepend +does not come with the distribution at this time, but will be available in +a patch in the near future) +.SH "MULTI PROCESSING" +If the architecture supports it then \fBdmake\fP is capable of making a target's +prerequisites in parallel. \fBdmake\fP will make as much in parallel as it +can and use a number of child processes up to the maximum specified by +MAXPROCESS or by the value supplied to the \-P command line flag. +A parallel make is enabled by setting the value of MAXPROCESS (either directly +or via \-P option) to a value which is > 1. +\fBdmake\fP guarantees that all dependencies as specified in the makefile are +honored. A target will not be made until all of its prerequisites have been +made. Note that when you specify \fB-P 4\fP then four child processes are +run concurrently but \fBdmake\fP actually displays the fifth command it will +run immediately upon a child process becomming free. This is an artifact of +the method used to traverse the dependency graph and cannot be removed. +If a parallel make is being performed then the following restrictions on +parallelism are enforced. +.RS +.IP 1. +Individual recipe lines in a non-group recipe are performed sequentially in +the order in which they are specified within the makefile and in parallel with +the recipes of other targets. +.IP 2. +If a target contains multiple recipe definitions (cf. :: rules) then these are +performed sequentially in the order in which the :: rules are specified within +the makefile and in parallel with the recipes of other targets. +.IP 3. +If a target rule contains the `!' modifier, then the recipe is performed +sequentially for the list of outdated prerequisites and in parallel with the recipes of other targets. +.IP 4. +If a target has the .SEQUENTIAL attribute set then all of its prerequisites +are made sequentially relative to one another (as if MAXPROCESS=1), but in +parallel with other targets in the makefile. +.RE +.PP +Note: If you specify a parallel make then +the order of target update and the order in which the associated recipes are +invoked will not correspond to that displayed by the \-n flag. +.SH "CONDITIONALS" +.B dmake +supports a makefile construct called a \fIconditional\fR. It allows +the user +to conditionally select portions of makefile text for input processing +and to discard other portions. This becomes useful for +writing makefiles that are intended to function for more than one target +host and environment. The conditional expression is specified as follows: +.sp +.RS +.nf +\&.IF \fIexpression\fR + ... if text ... +\&.ELIF \fIexpression\fR + ... if text ... +\&.ELSE + ... else text ... +\&.END +.RE +.fi +.sp +The .ELSE and .ELIF portions are optional, and the conditionals may be +nested (ie. the text may contain another conditional). +\&.IF, .ELSE, and .END +may appear anywhere in the makefile, but a single conditional expression +may not span multiple makefiles. +.PP +\fIexpression\fR can be one of the following forms: +.sp +String evaluation +.br +\t<text> | <text> == <text> | <text> != <text> +.sp +Numeric evaluation +.br +\t<text> <= <text> | <text> >= <text> +.sp +Boolean evaluation +.br +\t( <text> ) | <text> || <text> | <text> && <text> +.sp +where \fItext\fR is either text or a macro expression. In any case, +before the comparison is made, the expression is expanded. The text +portions are then selected and compared. In the case of the numeric +comparisons enclosing quotes are removed after expanding the expressions +and the leading numerical parts are converted to an integer number. If no +numerical part is found this results to 0 (zero). The +string "12ab" for example evaluates to the number 12. +Expressions can be nested with () and the use of || or &&. +White space at the start and +end of the text portion is discarded before the comparison. This means +that a macro that evaluates to nothing but white space is considered a +NULL value for the purpose of the comparison. +In the first case the expression evaluates TRUE if the text is not NULL +otherwise it evaluates FALSE. The remaining two cases both evaluate the +expression on the basis of a string comparison. +If a macro expression needs to be equated to a NULL string then compare it to +the value of the macro $(NULL). +You can use the $(shell ...) macro to construct more complex test expressions. +.SH "EXAMPLES" +.RS +.nf +.sp +# A simple example showing how to use make +# +prgm : a.o b.o + cc a.o b.o \-o prgm +a.o : a.c g.h + cc a.c \-o $@ +b.o : b.c g.h + cc b.c \-o $@ +.fi +.RE +.sp +In the previous +example prgm is remade only if a.o and/or b.o is out of date with +respect to prgm. +These dependencies can be stated more concisely +by using the inference rules defined in the standard startup file. +The default rule for making .o's from .c's looks something like this: +.sp +\&\t%.o : %.c; cc \-c $(CFLAGS) \-o $@ $< +.sp +Since there exists a rule (defined in the startup file) +for making .o's from .c's +\fBdmake\fR will use that rule +for manufacturing a .o from a .c and we can specify our dependencies +more concisely. +.sp +.RS +.nf +prgm : a.o b.o + cc \-o prgm $< +a.o b.o : g.h +.fi +.RE +.sp +A more general way to say the above using the new macro expansions +would be: +.sp +.RS +.nf +SRC = a b +OBJ = {$(SRC)}.o +.sp +prgm : $(OBJ) + cc \-o $@ $< +.sp +$(OBJ) : g.h +.fi +.RE +.sp +If we want to keep the objects in a separate directory, called +objdir, then we would write +something like this. +.sp +.RS +.nf +SRC = a b +OBJ = {$(SRC)}.o +.sp +prgm : $(OBJ) + cc $< \-o $@ +.sp +$(OBJ) : g.h +\&%.o : %.c + $(CC) \-c $(CFLAGS) \-o $(@:f) $< + mv $(@:f) objdir + +\&.SOURCE.o : objdir # tell dmake to look here for .o's +.fi +.RE +.sp +An example of building library members would go something like this: +(NOTE: The same rules as above will be used to produce .o's from .c's) +.sp +.RS +.nf +SRC\t= a b +LIB\t= lib +LIBm\t= { $(SRC) }.o +.sp +prgm: $(LIB) + cc \-o $@ $(LIB) +.sp +$(LIB) .LIBRARY : $(LIBm) + ar rv $@ $< + rm $< +.fi +.RE +.sp +Finally, suppose that each of the source files in the previous example had +the `:' character in their target name. Then we would write the above example +as: +.sp +.RS +.nf +SRC\t= f:a f:b +LIB\t= lib +LIBm\t= "{ $(SRC) }.o" # put quotes around each token +.sp +prgm: $(LIB) + cc \-o $@ $(LIB) +.sp +$(LIB) .LIBRARY : $(LIBm) + ar rv $@ $< + rm $< +.fi +.RE +.SH "COMPATIBILITY" +There are two notable differences between +.B \fBdmake\fR +and the standard version of BSD UNIX 4.2/4.3 Make. +.RS +.IP 1. .3i +BSD UNIX 4.2/4.3 Make supports wild card filename expansion for +prerequisite names. Thus if a directory contains a.h, b.h and c.h, then a +line like +.sp +\ttarget: *.h +.sp +will cause UNIX make to expand the *.h into "a.h b.h c.h". \fBdmake\fR +does not support this type of filename expansion. +.IP 2. .3i +Unlike UNIX make, touching a library member causes \fBdmake\fR +to search the library for the member name and to update the library time stamp. +This is only implemented in the UNIX version. +MSDOS and other versions may not have librarians that keep file time stamps, +as a result \fBdmake\fR touches the library file itself, and prints a warning. +.RE +.PP +\fBdmake\fP is not compatible with GNU Make. In particular it does not +understand GNU Make's macro expansions that query the file system. +.PP +.B dmake +is fully compatible with SYSV AUGMAKE, and supports the following AUGMAKE +features: +.RS +.IP 1. .3i +GNU Make style \fBinclude\fP, and \fBif/else/endif\fP directives are allowed +in non-group recipes. +Thus, the word \fBinclude\fP appearing at +the start of a line that is not part of a gruop recipe will be mapped +to the ".INCLUDE" directive that \fBdamke\fP uses. +Similarly, the words \fBifeq\fP,\fBifneq\fP,\fBelif\fP,\fBelse\fP, +and \fBendif\fP are mapped to their corresponding \fBdmake\fP equivalents. +.IP 2. .3i +The macro modifier expression $(macro:str=sub) is understood and is equivalent +to the expression $(macro:s/str/sub), with the restriction that str must match +the following regular expression: +.sp +\tstr[ |\et][ |\et]* +.sp +(ie. str only matches at the end of a token where str is a suffix and is +terminated by a space, a tab, or end of line) +Normally \fIsub\fP is expanded before the substitution is made, if you specify +\-A on the command line then sub is not expanded. +.IP 3. +The macro % is defined to be $@ (ie. $% expands to the same value as $@). +.IP 4. +The AUGMAKE notion of libraries is handled correctly. +.IP 5. +Directories are always made if you specify \fB\-A\fP. This is consistent +with other UNIX versions of Make. +.IP 6. +Makefiles that utilize virtual targets to force making of other targets work +as expected if AUGMAKE special target handling is enabled. For example: +.sp +.nf +\tFRC: +\tmyprog.o : myprog.c $(FRC) ; ... +.fi +.sp +Works as expected if you issue the command +.sp +\t'\fBdmake\fP \-A FRC=FRC' +.sp +but fails with a 'don't know how to make FRC' +error message if you do not specify AUGMAKE special target handling via +the \-A flag (or by setting AUGMAKE:=yes internally). +.RE +.SH "LIMITS" +In some environments the length of an argument string is restricted. +(e.g. MSDOS command line arguments cannot be longer than 128 bytes if you are +using the standard command.com command interpreter as your shell, +.B dmake +text diversions may help in these situations.) +.SH "PORTABILITY" +To write makefiles that can be moved from one environment to another requires +some forethought. In particular you must define as macros all those things +that may be different in the new environment. +.B dmake +has two facilities that help to support writing portable makefiles, recursive +macros and conditional expressions. The recursive macros, allow one to define +environment configurations that allow different environments for similar types +of operating systems. For example the same make script can be used for SYSV and +BSD but with different macro definitions. +.PP +To write a makefile that is portable between UNIX and MSDOS requires both +features since in almost all cases you will need to define new recipes for +making targets. The recipes will probably be quite different since the +capabilities of the tools on each machine are different. Different +macros will be needed to help handle the smaller differences in the two +environments. +.SH FILES +Makefile, makefile, startup.mk (use dmake \-V to tell you where the startup +file is) +.SH "SEE ALSO" +sh(1), csh(1), touch(1), f77(1), pc(1), cc(1) +.br +S.I. Feldman \fIMake - A Program for Maintaining Computer Programs\fP +.SH "AUTHOR" +Dennis Vadura, dvadura@wticorp.com +.br +Many thanks to Carl Seger for his helpful suggestions, +and to Trevor John Thompson for his many excellent ideas and +informative bug reports. Many thanks also go to those on the +NET that have helped in making \fBdmake\fP one of the best Make tools +available. +.SH BUGS +Some system commands return non-zero status inappropriately. +Use +.B \-i +(`\-' within the makefile) to overcome the difficulty. +.PP +Some systems do not have easily accessible +time stamps for library members (MSDOS, AMIGA, etc) +for these \fBdmake\fR uses the time stamp of the library instead and prints +a warning the first time it does so. This is almost always ok, except when +multiple makefiles update a single library file. In these instances it is +possible to miss an update if one is not careful. +.PP +This man page is way too long. +.SH WARNINGS +Rules supported by make(1) may not work if transitive closure is turned off +(-T, .NOINFER). +.PP +PWD from csh/ksh will cause problems if a cd operation is performed and +-e or -E option is used. +.PP +Using internal macros such as COMMAND, may wreak havoc if you don't understand +their functionality. diff --git a/dmake/man/readme b/dmake/man/readme new file mode 100644 index 000000000000..68c364e30056 --- /dev/null +++ b/dmake/man/readme @@ -0,0 +1,12 @@ +This directory contains the DMAKE manual page. + +The files found here are: + + dmake.tf - troff source for the manual page, you must use GNU groff + to typeset it or copy it as dmake.1 into a directory in + your search path for man pages to view it with the man + command. + + dmake.nc - a typeset version of the manual page containing no control + characters. Generated with: + "groff -mman -rcR=0 -Tlatin1 -P -bcu dmake.tf > dmake.nc" |