Noeud:Multiple Directories, Noeud « Next »:, Noeud « Previous »:Make Conditionals, Noeud « Up »:GNU Make



Multiple Directories

Except in the most trivial of projects, source files are usually arranged in subdirectories. Unfortunately, because of the way it is designed, Make is difficult to use with files that are not in the same directory as the Makefile itself. Because of this, it is best to put a separate Makefile in each directory, and make each Makefile responsible for only the source files in its own directory. For example:

     $ tree -P Makefile m4
       m4
       |-- Makefile
       |-- config
       |   `-- Makefile
       |-- doc
       |   `-- Makefile
       |-- examples
       |   `-- Makefile
       |-- intl
       |   `-- Makefile
       |-- m4
       |   `-- Makefile
       |-- modules
       |   `-- Makefile
       |-- po
       |   `-- Makefile
       |-- src
       |   `-- Makefile
       `-- tests
           `-- Makefile
     
       10 directories
     

In order to have the build process recurse through the source tree, the toplevel Makefile must descend into the subdirectories and start a new Make process in each. Typically, the order that the subdirectories are visited is critical. For the project depicted above, the build must first visit the po and intl directories to build the internationalisation libraries1, then the m4 subdirectory to build libm4.a, which uses the internationalisation library, before building the loadable modules which rely on libm4.la and so on, and so forth, until the build completes by building the documentation in the doc subdirectory.

GNU Make sets the variable $(MAKE) to the name with which make was invoked. For example, many vendor environments install GNU Make as gmake - blindy running make from the command part of a rule would not then invoke gmake, even if the user had invoked gmake on the top level Makefile.

     SUBDIRS = intl po config m4 modules src tests examples doc
     
     all:
             @for subdir in $(SUBDIRS); do \
               echo "Making all in $$subdir"; \
               cd $$subdir && $(MAKE) all; \
             done
     
     Example 5.30: Top level Makefile fragment for recursing subdirectories
     

Using $(MAKE) in example 5.30 ensures that the recursive make invocations in the command will execute the same program that the user originally ran to start the instance of make that read this Makefile.

With care, it is possible to set up a Makefile that, in addition to running recursive make invocations on Makefiles in subdirectories, will also perform some builds in its own directory. And there is certainly nothing to prevent you from setting up a build tree that has more than nested levels of Makefile. Later in Automake, we will explain how Automake manages all of the details of recursion for you.


Notes de bas de page

  1. We already covered this in (FIXME: xref chapter 2.).