# Builds involving multiple directories

One of the main motivations for writing makepp was to make it easy to do reliable builds involving multiple makefiles scattered across several directories. Makepp avoids the problems associated with recursive makes and is much easier to use. It also continues to support the old kludgy way of invoking make recursively, though this is deprecated.

For a discussion of why recursive invocations of make are not encouraged, see the section on recursive make in legacy makefiles.

Makepp's solution is to load all makefiles into the same make process. This way, cross-makefile dependencies can be accurately expressed. Each makefile needs simply to refer to the files it needs, and if these files are built by other makefiles, makepp figures that out automatically. It mixes rules from different makefiles, first executing a rule from one makefile and then a rule from a different makefile, as necessary.

The separate makefiles do not interfere with each other (unless they contain conflicting rules for building the same file) because makepp keeps all variables local to each makefile. It also tags each rule with the directory its makefile was found in, and automatically cd's to that directory before executing the rule.

Each makefile can be written entirely independently of the others. No makefile needs to know anything about the other makefiles (unless it explicitly has to load them; see below). In general (unless you use the `-f` option to specify the location of the makefile), the makefile may assume that all shell commands are executed with the default directory as the directory that contains the makefile; it does not have to know where the top level makefile for the build is. In fact, makefiles which were not originally designed to work together will usually work together seamlessly.

The only restriction that this architecture places on makefiles is that there can be only one makefile per directory. Makepp will give an error message if you try to load two makefiles for the same directory. This is for technical internal reasons (the phony targets would get confused).

How does makepp figure out which makefiles are needed? There are two ways (besides explicit invocation of recursive make, which is discouraged): it can guess where the makefiles are, or you can tell it explicitly.

## Implicit makefile loading

The simplest way of building a system that spans multiple directories is to allow makepp to figure out automatically which makefiles need to be loaded. If makepp needs to use a file, and there is currently no build command known for the file, makepp first looks in the directory that contains or will contain that file to see if there is a makefile there. It first looks for `Makeppfile`, then `makefile`, then `Makefile`. If one of these files is found, it is loaded into makepp, and any build instructions that it contains are now available.

Makepp does not attempt to load makefiles from directories which are not writable. This is because it couldn't build files in such directories anyway, and it assumes that they won't change since the user running makepp can't write to them.

You can also tell makepp to ignore makefiles in directories by using the `no_implicit_load` statment in one of your makefiles. This can be useful if you don't want to spend the time building a large sub-project which you know hasn't changed, or if one of your directories contains a file called "makefile" but it's for some other version of make and contains directives that makepp does not understand.

Since most existing makefiles are designed to produce output files in the same directory as the makefile, this rule usually finds the relevant build instructions.

Implicit makefile loading can make builds that span even many directories quite simple. Each directory simply needs to contain a makefile that builds anything which is supposed to be contained in that directory. If any other makefile needs to access a file in that directory, it simply lists it in a dependency list; makepp then automatically figures out that it needs to read in another makefile.

For a concrete example of this, see the tutorial section on working with multiple directories.

Implicit loading will not work for you if:

- Your makefiles are located in a different directory than the files they produce, e.g., if you put architecture-dependent binaries in a separate directory.
- You need to override some variables in the makefile.
- Your makefile is not called `Makeppfile`, `makefile`, or `Makefile`. (But why did you pick such a strange name for your makefile?)

If any of these are true, then you need to use the `load_makefile` statement.

Sometimes implicit makefile loading loads too many makefiles. For example, if you have many directories which contain makefiles, but they just contain libraries which are never modified and never need to be recompiled, then there is no real reason for makepp to load the makefiles from those directories. You can make the directories non-writable, or turn off implicit makefile loading altogether by adding the `-noimplicit-load` option to the command line, or turn it off on a directory-by-directory basis by using the `no_implicit_load` statement in one of your makefiles.

Implicit makefile loading is also automatically turned off if makepp sees a reference to `$(MAKE)` anywhere in your makefile. `$(MAKE)` is used for recursive make invocations in old makefiles. If makepp sees `$(MAKE)`, it assumes that directories are taken care of explicitly by recursive invocations of make. Experience shows that implicit loading often gets in the way for legacy makefiles that use recursive make, and so makepp turns it off.

## The load_makefile statement

    load_makefile subdir1/Makefile /other/dir/Makeppfile
    load_makefile VAR=value dir1 dir2

(See the section on makefile syntax for the syntax.)

This causes makepp to load the rules in the specified makefile(s). You must use this statement if:

- Implicit makefile loading is not finding all the necessary makefiles.
- You need to override a variable in the makefile.
- You need to specify the makefile's name.
- You have turned off implicit makefile loading.

If you have implicit makefile loading turned on, and you are using the `load_makefile` statement because you need to override a variable in the other makefile, then the `load_makefile` statement must occur before any rules that depend on files that the other makefile builds. Otherwise, the makefile will first be implicitly loaded, and then when you try to load the makefile again with a different set of variables, makepp will detect this and give you an error message.

Table of contents | Next (repositories and variant builds) | Previous (command line syntax)
Last modified: Wed May 16 09:26:51 PDT 2001