DMAKE

Section: Unsupported Free Software (p)
Updated: UW
Index Return to Main Contents
 

NAME

dmake - maintain program groups, or interdependent files  

SYNOPSIS

dmake [-P#] [-{f|C|K} file] [-{w|W} target ...] [macro[[!][*][+][:]]=value ...] [-v{cdfimt}] [-ABcdeEghiknpqrsStTuVxX] [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 prerequisites 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 special 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 exceptions.

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 target. 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" section), 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 standard error from any child processes and from the dmake process 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 definitions in the makefile to override definitions in the environment.
-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 continue to make as much as possible.
-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 found, the line is expanded and invoked, thereby enabling recursive makes to give a full description of all that they will do. The check for "$(MAKE)" 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 PROCESSING" 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 commands 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.
-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)
-v[dfimt]
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 [dfimt] 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 -vdfimt). The meanings of the optional flags are:
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.
t
Keep any temporary files created; normally they are automatically deleted.
-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 function 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.
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.
TEXT DIVERSIONS
How to use text diversions in recipes and macro expansions.
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.
RUN-TIME MACROS
Discussion of special run-time macros such as $@ and $<.
FUNCTION MACROS
GNU style function macros, only $(mktmp ...) for now.
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.
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.
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 variable MAKESTARTUP defined in the current environment.
3.
The location given as the value of the macro MAKESTARTUP defined internally within dmake.

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 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 makefiles 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 prerequisite 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 additional 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 specified makefile. The graph is rooted at the special target .ROOT. .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 .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 :;

which nicely emulates the behaviour of Sun's make extensions. The building of .ROOT's prerequisites is always forced to be sequential.  

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.




-> Conditional-Macro-Definition
-> Conditional
-> Rule-Definition
-> Attribute-Definition

-> MACRO [!]*= LINE
-> MACRO [!]:= LINE
-> MACRO [!]*:= LINE
-> MACRO [!]+= LINE
-> MACRO [!]+:= LINE




   Makefile
[ .ELIF expression
   Makefile ]
[ .ELSE
   Makefile ]
.END

-> STRING == LINE
-> STRING != LINE


   [ recipe ]

target-definition -> targets [attrs] op { PREREQUISITE } [; rcp-line]

-> "target" { targets }

-> TARGET

-> "attribute" { attrs }




-> ^
-> !
-> -
-> |

-> [@][%][-] [


   { LINE }

]



-> .GROUP
-> .IGNORE
-> .IGNOREGROUP
-> .LIBRARY
-> .MKSARGS
-> .NOINFER
-> .NOSTATE
-> .PHONY
-> .PRECIOUS
-> .PROLOG
-> .SETDIR=path
-> .SILENT
-> .SEQUENTIAL
-> .SWAP
-> .USESHELL
-> .SYMBOL
-> .UPDATEALL

-> .EXIT
-> .EXPORT
-> .GROUPEPILOG
-> .GROUPPROLOG
-> .IMPORT
-> .INCLUDE
-> .INCLUDEDIRS
-> .MAKEFILES
-> .REMOVE
-> .SOURCE
-> .SOURCE.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 continued over several physical lines by terminating it with a single backslash 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. \# 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 -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. When processing 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. The sequence \<nl> is treated as white space during recipe expansion and 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 line. The \<nl> sequence is deleted from macro values when they are expanded.

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 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 specifications 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.
.FIRST
Used in conjunction with .INCLUDE. Terminates the inclusion 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 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 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.
.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 prerequisites.
.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 directory 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 `:' 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.
.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 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.

All attributes are user setable and except for .UPDATEALL, .SETDIR 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 and .SETDIR attributes 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 : ...

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 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.  

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 forcing the specified macro assignment.

When dmake 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 -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 specification of the -e or -E flags are subject to expansion when used.