# Makepp's build algorithm

Makepp differs from the standard unix make in fundamental ways.

## Reverse vs. forward inference

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.

When makepp encounters the above pattern rule, it searches for all files in the directory matching the pattern `%.cxx` (i.e., `**/*.cxx`, where the wildcard `**` means to match any number of intervening directories). 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:

- Header files which have been detected by the automatic dependency scanner don't have to exist; makepp knows where they will be. (Most other solutions to this problem assume that any headers which don't exist yet are in the current directory.)
- Wildcards can match files which don't exist yet but can be built.
- A complete list of all buildable files is available via the `$(only-targets )` function.

## Files vs. textual patterns

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.)

## Stored build information

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:

- The signature of this file on the last build, so we know if the file itself has changed.
- The names of each dependency file, including include files and other files inferred automatically. If this list changes, then makepp assumes it needs to rebuild.
- The signature of each dependency. This way, makepp knows to rebuild not only when the dependencies are newer than the target, but when they change at all. This also makes it possible to use other kinds of signatures, such as cryptographic checksums, rather than the file date.
- The entire build command (and its cwd). This way if you change the build options, makepp knows to rebuild even if the files themselves haven't changed.
- The architecture. If you have compiled your program on linux and then switch to solaris, makepp automatically knows to recompile everything.

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.

Table of contents | Next (extending makepp) | Previous (automatic dependency inferences)
Last modified: Sat Aug 19 14:30:20 PDT 2000