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.sd.mk'.
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.sd.mk 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.sd.mk'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.sd.mk
54 can simply refer to files in other subdirectories directly.
56 Invocation, "recursive" per-directory targets
57 ---------------------------------------------
59 Arrangements are made so that when you run `make foo' in a
60 subdirectory, it is like running the whole toplevel makefile, from the
61 toplevel, as `make subdir/foo'. If `subdir/foo' is a file that might
62 be built, that builds it.
64 But `foo' can also be a conventional target like `all'.
66 Each subdirectory has its own `all' target. For example a
67 subdirectory `src' has a target `src/all'. The rules for these are
68 automatically generated from the settings of the per-directory
69 &TARGETS variables. &TARGETS is magic in this way. (In
70 src/Subdir.sd.mk, &TARGES of course refers to a make variable called
73 The `all' target in a parent directory is taken to imply the `all'
74 targets in all of its subdirectories, recursively. And in the
75 autogenerated stub Makefiles, `all' is the default target. So if you
76 just type `make' in the toplevel, you are asking for `&all'
77 (<subdir>/all) for every directory in the project.
79 In a parallel build, the rules for all these various subdirectory
80 targets may be in run in parallel: there is only one `make'
83 You can define other per-directory recursive targets too: simply
84 mention (usually, by setting) the variable &TARGETS_zonk, or whatever.
85 This will create a src/zonk target.
86 Unlike `all', these other targets only exist in areas of the project
87 where at least something mentions them. So for example, if
88 &TARGETS_zonk is mentioned in src but not lib, `make zonk' in
89 lib will fail. If you want to make a target exist everywhere,
90 mention its name in Perdir.sd.mk (see below).
92 Perdir.sd.mk, inclusion
93 -----------------------
95 The file Perdir.sd.mk in the toplevel of fthe source is automatically
96 processed after each individual directory's Subdir.sd.mk, and the
97 &-substituted contents therefore appear once for each subdirectory.
99 This lets you do per-directory boilerplate. Some useful boilerplate
100 is already provided in subdirmk, for you to reference like this:
101 &:include subdirmk/cdeps.sd.mk
102 &:include subdirmk/clean.sd.mk
103 For example you could put that in Perdir.sd.mk.
108 If want to set global variables, such as CC, that should only be done
109 once. You can put them in your top-level Subdir.sd.mk, or a separate
110 file you `include' and declare using SUBDIRMK_MAKEFILES.
112 Subdirectory templates `.sd.mk' vs plain autoconf templates `.mk.in'
113 --------------------------------------------------------------------
115 There are two kinds of template files.
117 Filename .sd.mk .mk.in
119 Processed by &-substitution, autoconf only
122 Instantiated Usu. once per subdir Once only
124 Need to be mentioned No, but Subdir.sd.mk All not in subdirmk/
125 in configure.ac? via SUBDIRMK_SUBDIRS via SUBDIRMK_MAKEFILES
127 How to include `&:include foo.sd.mk' `include foo.mk'
128 in all relevant .sd.mk in only one
129 (but not needed for Subdir.sd.mk
132 If you `include subdirmk/regen.mk', dependency management and
133 automatic regeneration for all of this template substitution, and for
134 config.status etc. is done for you.
139 In general & expands to the subdirectory name when used for a
140 filename, and to the subdirectory name with / replaced with _ for
143 Note that & is processed *even in makefile comments*. The substitutor
144 does not understand make syntax, or shell syntax, at all. However,
145 the substitution rules are chosen to work well with constructs which
146 are common in makefiles.
148 In the notation below, we suppose that the substitution is being in
149 done in a subdirectory sub/dir of the source tree. In the RH column
150 we describe the expansion at the top level, which is often a special
151 case (in general in variable names we call that TOP rather than the
154 &CAPS => sub_dir_CAPS or TOP_CAPS
155 &lc => sub/dir/lc or lc
156 Here CAPS is any ASCII letter A-Z and lc is a-z.
157 The assumption is that filenames are usually lowercase and
158 variables usually uppercase. Otherwise, use another syntax:
160 &_ => sub_dir_ or TOP_
161 &/ => sub/dir/ or nothing
162 &=_ => sub_dir or TOP
164 &^ => $(top_srcdir)/sub/dir or $(top_srcdir)
165 &~ => $(abs_top_srcdir)/sub/dir or $(abs_top_srcdir)
167 && => && for convenience in shell runes
168 \& => & general escaping mechanism
173 Convenience syntax for prefixing multiple filenames.
174 Introduced by & followed by lwsp (space or tab).
175 Each lwsp-separated non-ws word is prefixed by &/ &^/ &~/
176 respectively. No other & escapes are recognised.
177 This processing continues until a & preceded by lwsp,
178 or until EOL (the end of the line), or \ then EOL.
180 &:<directive> <args>....
181 recognised at start of line only (possibly after lwsp)
182 args are processed for &
184 &:include filename filename should usually be foo.sd.mk
185 &:-include filename tolerate nonexistent file
187 &!<lwsp> disables & until EOL (and then disappears)
190 changes the escape sequence from & to literally STUFF
191 STUFF may be any series of of non-whitespace characters,
192 and is terminated by EOL or lwsp. STUFF and the lwsp
195 After this, write STUFF instead of &, everywhere.
196 The effect is global and lasts until the next setting.
197 It takes effect on &:include'd files too, so maybe set
198 it back before using &:include.
203 STUFF!& set escape back to &
206 Handled specially. If mentioned, declares that
207 this subdirectory ought to have a target `things'.
208 (`all' if not specified). The rule will be
209 &/things:: $(&TARGETS_things)
211 You may extend it by adding more :: rules for the target,
212 but the preferred style is to do things like this:
213 &TARGETS_check += & test-passed.stamp
215 It is important to mention &TARGETS_things at least once in
216 the context of each applicable directory, because it arranges
217 that the *parent* will also have a `things' target which
218 recursively implies this directory's `things'.
220 Must be spelled exactly &TARGETS_things. &_TARGETS_things,
221 for example, does not work. But mentioning it in a #-comment
222 *does* work because the & filter does not care about comments.
224 `all' is extra special: every directory has an `all'
225 target, which corresponds to &TARGETS.
227 Subdirectory and variable naming
228 --------------------------------
230 The simple variable decoration scheme does not enforce a strict
231 namespace distinction between parts of variable names which come from
232 subdirectory names, and parts that mean something else.
234 So it is a good idea to be a bit careful with your directory naming.
235 `TOP', names that contain `_', and names that are similar to parts of
236 make variables (whether conventional ones, or ones used in your
237 project) are best avoided.
239 If you name your variables in ALL CAPS and your subdirectories in
240 lower case with `-' rather than `_', there will be no confusion.
247 Copyright 2019 Mark Wooding
248 Copyright 2019 Ian Jackson
250 subdirmk and its example is free software; you can redistribute it
251 and/or modify it under the terms of the GNU Library General Public
252 License as published by the Free Software Foundation; either
253 version 2 of the License, or (at your option) any later version.
255 This is distributed in the hope that it will be useful, but
256 WITHOUT ANY WARRANTY; without even the implied warranty of
257 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
258 Library General Public License for more details.
260 You should have received a copy of the GNU Library General Public
261 License along with this library as the file LGPL-2.
262 If not, see https://www.gnu.org/.
264 Individual files generally contain the following tag in the copyright
265 notice, instead of the full licence grant text:
266 SPDX-License-Identifier: LGPL-2.0-or-later
267 As is conventional, this should be read as a licence grant.
269 Contributions are accepted based on the git commit Signed-off-by
270 convention, by which the contributors' certify their contributions
271 according to the Developer Certificate of Origin version 1.1 - see
272 the file DEVELOPER-CERTIFICATE.
274 Where subdirmk is used by and incorporated into another project (eg
275 via git subtree), the directory subdirmk/ is under GNU LGPL-2.0+, and
276 the rest of the project are under that other project's licence(s).
277 (The project's overall licence must be compatible with LGPL-2.0+.)