1 subdirmk - assistance for non-recursive use of make
2 ===================================================
7 Peter Miller's 1997 essay _Recursive Make Considered Harmful_
8 persuasively argues that it is better to arrannge to have a single
9 make invocation with the project's complete dependency tree, rather
10 than the currently conventional `$(MAKE) -C subdirectory' approach.
12 However, actually writing a project's build system in a non-recursive
13 style is not very ergonomic. The main difficulties are:
14 - constantly having to write out long file and directory names
15 - the lack of a per-directory make variable namespace means
16 long make variables (or namespace clashes)
17 - it is difficult to arrange that one can cd to a subdirectory
18 and say `make all' and have something reasonable happen
19 (to wit, build an appropriate subset)
21 `subdirmk' is an attempt to solve these problems (and it also slightly
22 alleviates some of the boilerplate needed to support out-of-tree
28 The developer is expected to write a makefile fragment in each
29 relevant subdirectory called `Subdir.mk.in'.
31 These fragments may contain ordinary make language.
33 However, the sigil & is treated specially. By and large, it refers to
34 `the current directory'. There are a variety of convenient
37 The result is that to a large extent, the Subdir.mk.in has an easy way
38 to namespace its "local" make variables, and an easy way to refer to
39 its "local" filenames.
41 The Subdir.mk.in's are filtered, fed through autoconf in the usual way
42 (for @..@-substitutions) and included by one autogenerated toplevel
45 So all of the input is combined and passed to one make invocation. (A
46 corollary is that there is no enforcement of the namespacing:
47 discipline is required to prefix relevant variable names with &, etc.
49 Each subdirectory is also provided with an autogenerated `Makefile'
50 which exists purely to capture ordinary make invocations and arrange
51 for something suitable to happen.
53 Where there are dependencies between subdirectories, each Subdir.mk.in
54 can simply refer to files in other subdirectories directly.
56 Per-directory targets, "recursion"
57 ----------------------------------
59 Each subdirectory has its own `all' target. For example a
60 subdirectory `src' has a target `src/all'. The rules for these are
61 automatically generated from the settings of the per-directory
62 &TARGETS variables. (In src/Subdir.mk.in, this of course refers to a
63 make variable called src_TARGETS.)
65 The `all' target in a parent directory is taken to imply the `all'
66 targets in all of its subdirectories, recursively. And in the
67 autogenerated stub Makefiles, `all' is the default target. So if you
68 just type `make' in the toplevel, you are asking for `&all'
69 (<subdir>/all) for every directory in the project.
71 In a parallel build, the rules for all these various subdirectory
72 targets may be in run in parallel: there is only one `make'
75 There may also be other
82 (None of this prevents
88 https://web.archive.org/web/20150330111905/http://miller.emu.id.au/pmiller/books/rmch/
93 &CAPS => subdir_CAPS or TOP_CAPS
94 &lc => subdir/lc or lc
97 &/ => subdir/ or nothing
100 &^ => $(top_srcdir)/subdir or $(top_srcdir)
101 &~ => $(abs_top_srcdir)/subdir or $(abs_top_srcdir)
106 & thing thing... & => each thing prefixed by &/ &^/ &~/ resp
107 & ^ thing thing... & each thing is any non-ws
108 & ~ thing thing... & & may be omitted before EOL or before \EOL
109 other &'s not recognised
111 start of line (maybe after ws):
112 &:<directive> <args>....
113 args are processed for & first
114 &:include filename filename should usually be foo.mk.in
117 CAPS is [A-Z][0-9_A-Z]*(?!\w)
118 lc is [a-z][-+,0-9_a-z]*(?!\w)
120 &!<spaces or tabs> disables & *until* EOL (and disappears)
122 &!STUFF<lwsp> STUFF is recognised instead of &
123 the terminating lwsp is discarded too
124 may also occur at eol
127 STUFF!& now & is recognised instead (ie back to normal)
131 &!@@@ @@@ is recognised instead of &
134 &TARGETS[_things] is handled specially
135 must be spelled precisely this way
136 if no _things, means _all
138 Also, `all' is weird in that it is present even if not specified