title: How to write a simple hierarchical Makefile?
body: <p>Some days ago I posted an answer in stack overflow about how to write a hierarchical make (http://stackoverflow.com/questions/1498213/make-hierarchical-make-file). The answer was deleted, therefore I assume that it was completely wrong or off topic (or both). </p>
  
  <p>I would like to know how to write hierarchical Makefile. This is a Makefile that calls several Makefiles in sub-directories. I assume a directory structure like:</p>
  
  <pre><code>- project
    |--module1
        |--Makefile
        |--...
    |--module2
       |--Makefile
       |--module2.1
       |--module2.2  
       |--...
    |--module3
       |--Makefile
       |--...
    |--etc
  </code></pre>
  
  <p>I also assume that the project members have only agreed only upon a minimal set of makefile targets like: all (default), clean, install, and so. So, the following commands including make flags will be propagate to the modules:</p>
  
  <pre><code>cd project
  make clean  
  make -k
  make install
  #etc
  </code></pre>
  
  <p>What is wrong with the following project Makefile:</p>
  
  <pre><code>PACKAGES = \
      module1 \
      module2 \
      emodule3
  
  VIRTUAL_PACKAGES = $(addsuffix /.virtual.Makefile,${PACKAGES})
  
  TARGETS=clean install all
  
  .PHONY: $(TARGETS)
  default: all
  
  FLAGS = $(ifeq $(MAKEFLAGS) "","",-$(MAKEFLAGS))
  
  $(TARGETS): $(VIRTUAL_PACKAGES)
  
  $(VIRTUAL_PACKAGES): 
      $(MAKE) $(FLAGS) -C $(@D) $(MAKECMDGOALS)
  </code></pre>
  
  <p>yes, the $VIRTUAL_PACKAGES in the Makefile looks odd. The alternative of mixing a for loop is a bit shorter but I am not sure if it is better (as I need to rely on bash):
      PACKAGES = \
          module1 \
          module2 \
          emodule3</p>
  
  <pre><code>TARGETS=clean install all
  
  .PHONY: $(TARGETS)
  default: all
  
  FLAGS = $(ifeq $(MAKEFLAGS) "","",-$(MAKEFLAGS))
  
  $(TARGETS): 
      for p in $(PACKAGES) ; do $(MAKE) $(FLAGS) -C $$p $@ || break; done
  </code></pre>
  
  <p>Thanks!</p>