I intend to gather here descriptions for rationales for techniques
used and choices made in the makefiles.
I made a main makefile at the top of the makefile structure.
This is intended as the point where to build the whole
p1tre VOB.
This is however not the place where dependencies between the
different targets should be described: the natural place for this
would be within every pob's own main makefile.
As this is currently not done, the top makefile cannot be run with
parallel building enabled.
For this to work, one needs that the dependencies are:
The solution lies in producing for each target in the top makefile
a DO (i.e. a tag file), whose CR would reflect the actual
dependencies.
This in turn requires that the main target in every pob
makefile produces a DO, which can be read in the respective
rule in the top makefile, thus infact concatenating the CR. This way,
the top makefile would access enough of information for the build
process to distribute intelligently the tasks.
pob_xxx: ( cd pob_dir; $(MAKE) tag ) cat pob_dir/tag > /dev/null touch pob_xxx
I made a test implementation
of this idea, which frightens me a bit by its complexity. A positive
side-effect of it is that the tag files in the top directory will
record the dependency upon the makefiles as well.
This file should include all the local configuration info, as
makefile macros.
This is however not fully true, since there must be a way to include this very file itself. The schema chosen to minimze the spreading of such information is to use two levels of soft links:
One might consider adding other kind of local configuration
information in this file (not only paths).
Makefile definitions may be available lexically before they are
being used, i.e. within rules. Therefore, to allow including makefiles
to add or modify definitions, these must be separated from the rules.
The last definition met takes precedence.
Note that one cannot override rules.
The only former component for inclusion. Kept for backwards
compatibility as a wrapper including the two latter.
This designates a makefile meant to be used directly on a
clearmake invocation, as opposed to a
makefile component to be included.
There is typically one such makefile per directory, named by
default Makefile.
There may however be several such main makefiles in a
directory, used for instance from the default Makefile in
recursive invocations of clearmake.
If we want to use parallel building, we
need to describe dependencies between the targets to be distributed.
This will enable clearmake to compute an order between the
various builds, and to avoid executing on one node a build script
depending on the result of one executed in parallel on an other, and
thus possibly non-available at the time when it would be needed.
We inevitably run into the need to describe remote
dependencies, i.e. dependencies on remote
targets. A work-around is needed to prevent the systematic
execution of build script depending on such targets.
This work-around will use
pseudo-targets and the special target
.NOTPARALLEL.
Instead of having a target $(PROGRAM) depend on the
remote target $(PROJDEPS), which would imply that
the executable is always linked anew, we can have the pseudo-target all depend in sequence
on $(PROJDEPS) and on $(PROGRAM).
This first idea fails however in presence of
parallel building: if this is enabled,
clearmake could distribute these two (sets of) targets on
different nodes, thus possibly linking the program with old versions
of the libraries, or failing to link it because the libraries would
not have been produced yet.
Thus, either Parallel building must be
disabled, or one must
recursively invoke clearmake. This
way, the subsession may apply build avoidance,
thus refraining from building again $(PROGRAM) if unnecessary.
This is a macro initialized to empty, but to be redefined in the
local main makefiles, to express the external
dependencies of a POB.
It corresponds to a remote target,
invoking the all target in a remote directory. The reason for
building the all target, instead of the actual library (or
other), is obviously to evaluate its potential external dependencies.
One small nit with recursive invocation
relates with the use of tag files as targets. In such a case, the
makefile in its globality gets recorded in the tag file's
CR, which leads to useless rebuilds.
Note that this may precisely be the intention, e.g. if one wants
to record the makefile for labelling purpose.
But in this case, the rule should not do anything in addition (the
subsession itself will anyway go through its own build avoidance step).