Dmake Dmake Reference Library




OPTIMIZED

 


Release Notes

The following are release notes for dmake Version 4.0.

FULL RELEASE OF DMAKE, REPLACES VERSION 3.8, and 3.9
This distribution advances dmake. to Version 4.0, patch level 0. This release adds significant new functionality and makes one minor syntactic change in the makefile syntax. See the FUTURE FEATURES section for full details.
DETAILS OF CHANGES:
BUG FIXES
  1. cleaned up the code to fully remove the notion of an initial .SETDIR target and macro, had some remnants still present.

  2. If the first target in a file was a multi :: recipe then if any of the :: rules had no recipes an erroneous error was issued. This is now fixed and all of the :: targets behave in a manner consistent with non-:: targets that appear as the first target in the makefile.

  3. Fixed a bug with not properly setting the value of MAKESTARTUP if it was given on the command line.

  4. Specifying -u would not remove inferred prerequisites, they are now forcefully rebuilt and then removed if appropriate.

  5. $ (xx) now expands to just (xx), the $ is eaten.

  6. fixed a bug with erroneously freeing a directory string for a target.

  7. Under MSDOS the value of DirSepStr is now used to construct temporary file names when $(mktmp ...) is called. TMPDIR is still taken from the environment only since this is what the standard UNIX versions of tempnam do.

  8. Cleaned up -k processing in conjuction with -P#, it now behaves as expected.

  9. under MSDOS and related OS's surrounded the call to exec in spawn.c with a getcwd/setcwd pair, this way we will be cd'ed to the same place we were at before we ran the command. MSDOS is broken this way. This makes MSDOS scripts behave more like UNIX scripts. If you really want to say:
       cd foo
       commands...
    
    Then you will have to use a group recipe, you can do that easier by specifying the new .GROUP attribute.

  10. Fixed incompatibility with Augmake special target mapping, causing
         $(foo:suff1=suff2)
    
    to behave oddly. It now behaves as Sun and GNU Make do. Also suff1, and suff2 can now be arbitrary strings not containing an '=' character. Both are expanded before the substitution is performed.

  11. Macro expansion treated ':' as a modifier flag even in function macros.

  12. Fixed a small bug when parsing makefiles containing #'s in their recipe texts and when -B was specified, things now work as expected.

  13. The inference engine was incorrectly using the value of PREP, fixed.

  14. Fixed the expansion of $(foo)/{x y z}.o to produce
     
       a/x.o a/y.o a/z.o
    
    if foo = a, and
       a b/x.o a b/y.o a b/z.o
    
    if foo = a b and
       a/x.o b/x.o a/y.o b/y.o a/z.o b/z.o
    
    if the specified expansion is stated as:
       {$(foo)}/{x y z}.o
    
  15. Fixed a nasty bug in stat.c where the result of Build_path was not dupped when computing a new library path name.

  16. Modified COMMAND macro expansion to properly handle the expansion of commands that result in new recipe line attributes.

  17. Fixed a "feature" that prevented the correct handling of :: recipes.
       a.o :: a.c b.h
           echo "first recipe..."
           touch a.o
    
       a.o :: a.y b.h
           echo "second recipe..."
    
    now runs both recipes if b.h is newer than a.o. It used to run only the recipe for a.c. This was contrary to the documentation, and is probably not correct in general, in that by definition :: promisses to run all recipes that are out of date not just those that are out of date while the build continues.

  18. Fixed a bug with improper output on -n. It now reports work that it thinks should get done. The actual make may however do less, depending on how timestamps are actually modified during the run.

  19. Fixed a bug in detecting function macros, the following now works: (caused a core dump before)...
       bar = a b c
       foo = $(!null,$(bar:s/ /) -Lhithere)
    
       all:; echo $(foo)
    
    Thanks to "Brett M. Bergquist, brett.bergquist@corp.gdc.com" for pointing it out, and for providing the inspiration for the fix.
NEW FEATURES
  1. added .EXIT special target to exit from parsing a makefile and ignore the remainder to the end. If verbose is set then a message is issued.

  2. Made the macros DIRSEPSTR, and DIRBRKSTR user settable. The default setting for the MSDOS version of DIRSEPSTR is now \\, this allows it to correctly work for $(mktmp ...) diversions.

  3. Added two new attributes, and a command line option. .GROUP when specified with a target says execute this targets recipe as if it were a group recipe specified in [ ... ] notation.

    .IGNOREGROUP is an attribute variable that when set to "yes" says don't assume that a recipe line beginning with '[' is a group recipe. This in effect turns off group recipe parsing at the granularity of a single target or globally if specified alone in the makefile.

    -g is equivalent to saying .IGNOREGROUP:=yes at the start of startup.mk file.

  4. Path name construction for stat'ed targets has been modified to ignore './' entries and to reduce 'foo/..' sequences to NULL. That is, it makes little sense to have a path that cd's to a directory and then back up. This may result in having the value of $@ be somewhat unexpected depending on settings of .SOURCE and their friends. However this is infact the correct behaviour since the resolved pathname and the target name (as used internally) are not the same. dmake treats the resolved pathname as an attribute of the target that may infact be different from the target name itself.

  5. dmake attempts to make targets of .INCLUDE if the name cannot be found in any of the subdirectories specified in .INCLUDEDIRS. Specifying .INCLUDE .IGNORE causes dmake to not terminate if a prerequisite of .INCLUDE cannot be made.

  6. Added a .FIRST attribute for .INCLUDE special targets. Specifying .FIRST on a .INCLUDE line will attempt to include each named prerequisite and will halt after finding the first prerequisite that exists. If no prerequisite is successfully included and .IGNORE was not specified then an error is issued.

  7. Created new variable .NAMEMAX which when set to an integer value bounds the maximum length of a file name component. By default it is set to the compiled value NAME_MAX.

  8. $(shell,expand stuff) is a modification to $(shell ...) that causes the result to be expanded before it is returned. if ',expand' is not specified then the result is not expanded. The addition of expansion together with the new $(assign ...) macro allows external files to be read and to have them define macros as a result of the $(shell ...) execution.

  9. Generalized the expansion of Dynamic prerequisites. Specification of $$(foo) as a prerequisite is recursively expanded until the current cell contains no $ signs. If the expansion results in multiple white space separated tokens they are inserted into the prerequisite list in place of the initial dynamic prerequisite. If the new list contains additional dynamic prerequisites then they will be expanded when they are processed. NOTE: there is a limit on the number of times the same prerequisite can be recursively dynamically expanded, it is controlled by the setting of the macro DYNAMICNESTINGLEVEL, and is set to 100 by default. Thus the same prerequisite can be expanded dynamically a 100 times before dmake gives up with an error.

  10. Added -w and -W (whatif command line flags) and also significantly fixed up the processing for -n, to actually produce sensible output.

  11. Added '!' macro prefix indicating that the macro assignment is to be forced. That is, don't complain if the macro has been previously expanded. This can be used for single macro assignments:
       foo := stuff
       foo !:= silently blow away stuff in foo
       foo !+:= add this silently to previous value of foo
    
    or in conjunction with .SILENT as in:
       __.SILENT !:= $(.SILENT)
    
    change stuff to your hearts content...
    	.SILENT !:= $(__.SILENT)
    
  12. Added a $(macro:e) extension for returning the suffixes of a file list in the macro.

  13. Added a $(macro:u) and $(macro:l) modifiers for converting the macro value to all upper case and lower case respectively.

  14. Added a $(macro:i) modifier. It returns the inferred names for targets as given in a $< macro. For example:
       .SOURCE : objs
       OBJS = x.o y.o
    
       all:$(OBJS); echo $(OBJS:i)
    
    will produce
       objs/x.o y.o
    
    if x.o is found in the subdirectory 'objs'. The 'i' modifier can be mixed with all other modifiers.

  15. Added the .ROOT special target, it is the top level target that dmake builds when it starts to build targets. Also all user specified targets, either through the command line or by default in the makefile, are made prerequisites of the special target .TARGETS. By default dmake sets up the relationship that .ROOT depends on .TARGETS, and the world gets made. This allows you to customize within the makefile the order of building targets as well as which target is made 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 internally always forced to be sequential.

  16. Added dynamic macro assignment for use in recipes and otherwise. $(assign string) parses string as if it were a macro assignment string. string must contain a valid macro assignment, otherwise an error is issued.
       eg. $(assign foo := fred)
           $(assign $(indirect_macro_name) +:= $(morejunk))
    
    The result of this macro assignment is the name of the macro that was assigned, and NULL if the expression is not a valid assignment.

  17. Added a new macro modifier $(foo:^prefix) where prefix is either a quoted string "string" that is prepended to each token found in the value of $(foo) or prefix is a macro expression beginning with $, in which case prefix is expanded and the result is prepended to each token found in $(foo).

  18. Added a new macro modifier $(foo:+suffix) where suffix is either a quoted string "string" that is appended to each token found in the value of $(foo) or suffix is a macro expression beginning with $, in which case suffix is expanded and the result is appended to each token found in $(foo).

  19. You can now put $$@ into .SETDIR attribute strings, and the name of the target to be built is used for the attempted CD. Note that the final value of $@ will depend on the result of the stat search which is done after the change directory call forced by the .SETDIR attribute.

  20. Added a new function macro $(nil args) that always returns "", no matter what its arguments are.

  21. Added directory caching. It is enabled by default and causes dmake to cache the timestamps of entries in a directory the first time the directory is visited. Dmake tracks entries and performs actual stats as required to collect new timestamps, but does not perform stats on potential targets during inference after reading the directory contents the first time. setting .DIRCACHE=yes enables directory cache, and setting .DIRCACHE=no disbles it.

  22. Added conditional macros. 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 anywhere 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 :: definitions are activated when their respective recipe rules are built. 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 set conditional macro values available during construction of prerequisites.

    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.

  23. Enhanced the processing of .UPDATEALL, the following constructs are now allowed:
       a b .UPDATEALL : c
    
       a b .UPDATEALL :: d
    
    A .UPDATEALL causes all targets on the left to be treated as a single target all are updated whenever any one of them is made. As a sideffect, such targets are sorted in ascending alphabetical order, when any one of the group is constructed the value of $@ is the one that is first in the sorted set.
FUTURE FEATURES
  1. In the future the functionality of .UPDATEALL will be extended to %-meta rules as will the ability to infer multiple prerequisites. Thereby allowing inference of multiple targets from multiple prerequisites. In preparation for this functionality the following change was made to the parser.
       %.o : %.c %.f ; recipe
    
    used to be equivalent to:
       %.o : %.c ; recipe
       %.o : %.f ; recipe
    
    It now means defaults to:
       %.o : %.c ; recipe
    
    you must specify:
       %.o :| %.c %.f ; recipe
    
    to get the old behaviour. This is due to the fact that construction of the internal target graph has been been altered but the inference engine has not yet been updated to utilize the new functionality (I ran out of time).


Please send comments and suggestions to webmaster
Copyright  © 1996, 1997 by WTI Corp.,  All rights reserved.