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
- cleaned up the code to fully remove the notion of an initial
.SETDIR target and macro, had some remnants still
present.
- 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.
- Fixed a bug with not properly setting the value of
MAKESTARTUP if it was given on the command line.
- Specifying -u would not remove inferred prerequisites, they
are now forcefully rebuilt and then removed if appropriate.
- $ (xx) now expands to just (xx), the
$ is eaten.
- fixed a bug with erroneously freeing a directory string for a target.
- 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.
- Cleaned up -k processing in conjuction with
-P#, it now behaves as expected.
- 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.
- 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.
- Macro expansion treated ':' as a modifier flag even in
function macros.
- Fixed a small bug when parsing makefiles containing #'s in
their recipe texts and when -B was specified, things now
work as expected.
- The inference engine was incorrectly using the value of
PREP, fixed.
- 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
- Fixed a nasty bug in stat.c where the result of Build_path
was not dupped when computing a new library path name.
- Modified COMMAND macro expansion to properly handle the
expansion of commands that result in new recipe line attributes.
- 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.
- 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.
- 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
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- $(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.
- 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.
- Added -w and -W (whatif command line
flags) and also significantly fixed up the processing for
-n, to actually produce sensible output.
- 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)
- Added a $(macro:e) extension for returning the
suffixes of a file list in the macro.
- Added a $(macro:u) and $(macro:l)
modifiers for converting the macro value to all upper case
and lower case respectively.
- 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.
- 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.
- 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.
- 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).
- 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).
- 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.
- Added a new function macro $(nil args) that always returns
"", no matter what its arguments are.
- 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.
- 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.
- 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
- 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.
|