How makepp executes a makefile
Makepp's internals differ from the standard unix make in fundamental ways. This page describes the different philosophy in detail.
Makepp works in the opposite direction from the standard unix make. Traditional 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:
$(only_targets ) function.
$(infer_objects ) function is greatly simplified by
knowing what objects are available.
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 subdirectory
other_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.
If makepp is trying to build a target in a directory and doesn't have a rule for it yet, or if it is looking for files matching a wildcard in a directory, it will look in that directory to see if a makefile is present. If so, the makefile will be loaded automatically.
This means that you usually don't have to tell makepp explicitly where to find makefiles--all you have to do is to reference a file in another directory, and makepp will automatically figure out how to build it.
Implicit loading will occur only if the directory is writable to you. Thus if you want to prevent makepp from trying to build a bunch of things that never change, simply make the directory read-only.
If implicit loading gets in your way (i.e., makepp loads too many
makefiles and it wastes time, or else you really don't want it to try to
rebuild all the stuff described in the makefiles), you can turn it off
for all directories using the --noimplicit_load command line option,
or you can turn it off for selected directories using the
no_implicit_load statement in your makefile.