title: How to programmatically define targets in GNU Make?
body: <p>I am not aware of any way to define programatically targets in GNU Make. How is this possible?</p>
  
  <p>Sometimes one can go away <a href="https://stackoverflow.com/questions/8937500/how-to-generate-list-of-make-targets-automatically-by-globbing-subdirectories">with alternate methods</a>.  The ability to define programatically targets in Makefiles is however a very important to write and organise complex production rules with <code>make</code>. Examples of complex production rules are found in the build system of FreeBSD or in Makefile libraries such as <a href="https://github.com/michipili/bsdowl" rel="nofollow noreferrer">BSD Owl</a></p>
  
  <p>The <a href="https://stackoverflow.com/a/27293153/2654678">main differences</a> between shell scripts and Makefiles are:</p>
  
  <ul>
  <li><p>In a Makefile, the state of the program is given by the command line and the filesystem, so it is possible to resume a job after it has been interrupted. Of course, this requires to properly write the Makefiles, but even if this is rather hard, it is considerably easier than to achieve a similar effect with a shell script.</p></li>
  <li><p>In a Makefile, it is ridiculously easy to decorate a procedure with advises or decorate it with hooks, while this is essentially impossible in shell scripts.</p></li>
  </ul>
  
  <p>For instance, a very simple and useful pattern is the following:</p>
  
  <pre><code>build: pre-build
  build: do-build
  build: post-build
  </code></pre>
  
  <p>This presents the <code>build</code> target as a composite of three targets, one containing the actual instructions <code>do-build</code> and two other that are hooks, executed before and after <code>do-build</code>.  This pattern is used by many build systems written for BSD Make, which incidentally allows programmatic definition of targets, so that one can write in a batch:</p>
  
  <pre><code>.for _target in configure build test install
  .if !target(${_target})
  ${_target}: pre-${_target}
  ${_target}: do-${_target}
  ${_target}: post-${_target}
  .endif
  .endfor
  </code></pre>
  
  <p>The condition introduced by the <code>.if/.endif</code> block enables the user to use its own definition of any <code>${_target}</code>.</p>
  
  <p>What would be the translation of that snippet for GNU Make?</p>