Makepp's internals differ from the standard unix make in fundamental ways.
Makepp has a different philosophy from the standard make. The usual unix make is given a target to build, and then it finds a rule which matches the characters in the target filename. If the target is older than any of its dependencies of the rule, then it is rebuilt.
For example, consider this pattern rule:
%.o: %.cxx $(CXX) $(CXXFLAGS) -c $(input) -o $(output)
When make realizes it needs to make a file called
xyz.o
, it searches through its list of pattern rules
until it sees that xyz.o
matches the pattern
%.o
, and then it applies this rule.
Makepp works in the opposite direction. It first computes all files that it can possibly build by applying rules that match the characters in the dependency filenames. Then when it needs to build a file, it simply looks to see if it's one of the files that it knows how to build. The list of known files is stored based on the absolute filename.
When makepp encounters the above pattern rule, it searches
for all files in the directory matching the pattern
%.cxx
(i.e., *.cxx
). For each of these
files, it then remembers that it can produce the corresponding
.o
file. If subsequently makepp discovers that
it can make another .cxx
file that doesn't currently
exist, this rule will also be applied and the corresponding
.o
file will be marked.
This might seem somewhat inefficient, but it turns out not to be that slow in most cases, and it is often true that virtually all the files that can be built are in fact built. And knowing the complete list of files that can be built has several advantages:
infer_objects
function is
greatly simplified by knowing what objects are available.
$(only-targets )
function.
Makepp associates build commands with a target file, not
to a textual pattern for a filename. It is therefore not confused
by different names for the same file. Thus, for example,
makepp will know that ./xyz
and and
xyz
are the same file, whereas other make utilities may
not.
This is particularly important because (unlike the standard make) makepp loads makefiles from different directories. In order for the makefiles to be relatively independent, with no special position given to a top-level makefile, each makefile refers to all files relative to its own directory.
Thus if you load a makefile from the subdirectoryother_stuff
, and that makefile
refers to ../xyz
, makepp will again realize that
it's the same file referred to above. (It also won't be confused by
soft-linked directory names.)
makepp stores much more information about each file that it builds beyond just the date stamp (which is all that the standard make cares about). This information includes:
Makepp makes a subdirectory in every directory that it
touches called .makepp
. The build information for a
file filename in a directory is stored in
.makepp
filename. If you delete this
subdirectory or alter the files, makepp will rebuild all
affected files.