INDEX | PREV | NEXT

                            DMAKE V 2.0


 DMake   -   Dillon's MAKE utility (NOT Make or Lmk compatible.. better)

 The idea with DMake is to provide a powerful make utility through
 general features rather than specialized hacks.  DMake is governed
 by a few simple rules that can be combined into incredibly powerful
 operations.

 Generally you simply run 'DMake' and have a list of dependancies in
 your 'DMakefile' which DMake then executes.  The DMakefile may contain
 three different kinds of lines:

 (1) COMMENTS -- Any line beginning with a '#' is a comment and ignored

 # This DMakefile generates an executable for fubar, the compiler
 # options are as follows ...

 (2) ASSIGNMENTS -- Any line of the form <SYMBOL> = ...  is considered
 an assignment.  Any variable references from within the assignment will
 be resolved immediately.

 CFLAGS= -r
 SRCS= x.c y.c z.c

 (3) DEPENDANCIES: -- A line containing a list of symbols, a colon, and
 more symbols is assumed to be a dependancy.  Note that you cannot
 have a raw filename with a colon in it as that confuses DMake.
 Instead, use an ASSIGNMENT variable.

 Following the dependancy line is zero or more command lines --
 commands to run to resolve the dependancy, terminated with a
 blank line.

 NOTE: not only is a zero-command dependancy allowed, it is necessary in
 some cases.  A particular destination may have only ONE command list so
 if you have something like 'a.o : a.c' with a command list to compile
 the source into an object you can also have another dependancy such as
 'a.o : defs.h' which would NOT have any associated command list.


 dst1 ... dstN : src1 ... srcN
 command1
 command2  ...

 dst1 ... dstN : src1 ... srcN
 command1
 command2  ...

 Finally, note that a dst* or src* symbol does not need to be a
 filename.  It is perfectly valid to make up dummy names which are then
 used as the lhs of a dependancy that collects other dependancies
 together.


 DEPENDANCIES

 When declaring dependancies you may use four different forms.  The
 first form is to have a single destination and several sources.  This
 is intreted to mean that ALL the sources must be resolved before the
 single destination can be resolved via the command list for the
 dependancy.  The special variable, %(left), is set to the <dst> symbol
 and the special variable %(right) is set to ALL of the <src*> symbols

 For example, this form would be used to indicate that an executable
 depends on all the objects being resolved before you can run the link.

 (1) dst : src1 src2 src3 ... srcN

 The second form is the most useful in that it allows you to specify
 multiple 1 : 1 dependancies.  Thus, you can specify, for example, that
 each object file depends on its source file counterpart for ALL the
 files in your project on a single line and have a single command list
 representing what to do (to compile a source file into an object, say).

 In this case %(left) and %(right) are set to each dst* : src* pair
 individually and the command list is run for any individual pair that
 is out of date.

 (2) dst1 dst2 dst3 ... dstN : src1 src2 src3 ... srcN

 The next form may be used to specify that many files depend on one file
 being resolved.  An example of usage would be to make all the object
 files depend on one header file.  The command list, if any, is run for
 each dst* : src pair with %(left) set to the current dst* and %(right)
 set to the single source.

 (3) dst1 dst2 dst3 ... dstN : src

 The last form is esoteric but sometimes useful.  EACH dst* on the left
 hand side depends on the entire right hand side.  You can have an
 arbitrary number of symbols on either side.  %(left) will be set to a
 particular DST while %(right) will be set to all of the SRCs.

 for example, you could specify $(OBJS) :: $(HDRS)  -- make all objects
 depend on all headers causing a recompile to occur if any header is
 modified.

 (4) dst1 dst2 dst3 ... dstN :: src1 src2 ... srcI


 WILDCARDED FILE LIST REPLACEMENT // VARIABLE ACCESS

 DMake's most powerful feature is an easy to use file list replacement
 through options in a variable specification.  You may insert the
 contents of any variable using the form:

 $(SYMBOL)

 Furthermore, you can make modifications to the contents of the variable
 on the fly using:

 $(SYMBOL:wildcard)              only those files which match <wildcard>
 $(SYMBOL:wildcard:wildcard)     matching files and also do a conversion

 Simple */? wildcarding is used.  A wildcard may contain a colon or
 other punctuation but if it does you MUST surround it with quotes.  Here
 is a quick example:

 SRCS= a.c b.c c.c d.c xx.a
 OBJS= $(SRCS:*.c:"dtmp:%1.o")

 all:
     echo $(OBJS)

 (the result is 'dtmp:a.o dtmp:b.o dtmp:c.o dtmp:d.o')

 The first wildcard specification restricts which files from the list
 are to be taken -- 'xx.a' was ignored, as you can see.  Each '*' or '?'
 in the first wildcard specification corresponds to %N specifications
 in the second wildcard specification.  You can prepend, insert, or
 append text and freely mix or ignore items matched to create your
 destination file list.

 This capability allows you to specify your source files EXACTLY ONCE
 in the DMakefile and then use the file munging capability to convert
 them to the object file list, etc...

 You can embed variables within variables as with the following example
 (note that this time xx.a is included):

 OD= dtmp:fubar/
 SRCS= a.c b.c c.c d.c xx.a
 OBJS= $(SRCS:*.?:"$(OD)%1.o")

 all:
     echo $(OBJS)


 (the result is: 'dtmp:fubar/a.o dtmp:fubar/b.o dtmp:fubar/c.o
 dtmp:fubar/d.o dtmp:fubar/xx.o')

 As a side note, you may also specify '?' and '*' in the destination
 wildcard.  These are considered dummies and are equivalent to %N where
 N is incremented from 1..9 for each '?' or '*' encountered.

 You can use the capability anywhere in the DMakefile.  Another common
 thing to do is restrict your link line to include only the object files
 and skip the headers:

 $(EXE) : $(PROTOS) $(OBJS) $(HDRS)
     dcc %(right:*.o) -o %(left)


 ENVIROMENT VARIABLES

 2.0 local variables and 1.3/2.0 ENV: variables are fully accessible.
 Under 2.0 you can also modify local variables on the fly.
 DMake-specific variables override 2.0 local variables overide ENV:
 variables.

 Under 2.0, any command containing '<', '>', '`', or '|', or is an
 alias, will be run with System().  Thus, such commands may not be used
 to modify local variables or the local enviroment.  Also, such commands
 cannot be ^C'd due to the way AmigaDOS works.


 LINE CONTINUATION AND ESCAPES

 Any line may be continued by terminating it with a backslash ''.  It
 is possible to escape the special characters '$' and '%' by doubling
 them though this is only necessary if an open-parenthesis follows the
 '$' or '%' and you do not want it interpreted as a variable.

 It is possible to escape ':' and other special characters by assigning
 them (or a string containing them) to a variable


 COMMAND SHELL

 Under 2.0 commands that do not contain any sort of redirection are run
 with RunCommand().  If a command is an alias or there is some sort of
 redirection in the arguments it will be run with System().

 Under 1.3 everything is run with Execute()


 EXTREMELY ADVANCED CAPABILITIES

 Now, you may have noted earlier that I said you could not have any
 givem left-hand-side with more then one command list.  Take, for
 example:

 a.o : a.c
     dcc %(right) -o %(left)

 a.o : defs.h
     **** illegal to put command list here ****

 Actually, it isn't illegal.  When DMake encounters a dependancy without
 a command list it will automatically 'force' the next higher level
 dependancy of the same left-hand-side.  Therefore if you do not have a
 command list for the lower level left-hand-side things work as you
 expect.  Note that this requires all such null dependancies to exist
 AFTER the one that has the command list.

 If you do have two or more command lists for the same left-hand-side
 they will run independant of each other according to their individual
 right hand sides.  If several command lists apply then their order of
 execution will be bottom-up


 EXISTANCE OF A FILE OR DIRECTORY

 Another advanced feature quite useful in fully automating the
 compilation process is the ability to create a directory tree on
 the fly.  That is, if you have a projects called 'fubar' and want
 the objects to go into the directory DTMP:fubar/ you might want to
 have a dependancy that creates DTMP:fubar if it does not already
 exist.

 XX= dtmp:fubar

 $(XX) : $(XX)
 makedir %(left)


Converted using GuideML V1.6, a converter written by Richard Körber <shred@chessy.aworld.de>