chiark / gitweb /
more docs fixes
[subdirmk.git] / subdirmk / README
1 subdirmk - assistance for non-recursive use of make
2 ===================================================
3
4 Introduction
5 ------------
6
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.
11
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)
20
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
23 builds well).
24
25 Basic approach
26 --------------
27
28 The developer is expected to write a makefile fragment, in each
29 relevant subdirectory, called `Subdir.sd.mk'.
30
31 These fragments may contain ordinary make language.
32
33 However, the sigil & is treated specially.  By and large, it refers to
34 `the current directory'.  There are a variety of convenient
35 constructions.
36
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.
40
41 The Subdir.sd.mk's are filtered, fed through autoconf in the usual way
42 (for @..@-substitutions) and included by one autogenerated toplevel
43 makefile.
44
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.
48
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.
52
53 Where there are dependencies between subdirectories, each Subdir.sd.mk
54 can simply refer to files in other subdirectories directly.
55
56 Invocation, "recursive" per-directory targets
57 ---------------------------------------------
58
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.
63
64 But `foo' can also be a conventional target like `all'.
65
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
71 src_TARGETS.)
72
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.
78
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'
81 invocation at a time.
82
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).
91
92 Perdir.sd.mk, inclusion
93 -----------------------
94
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.
98
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.
104
105 Global definitions
106 ------------------
107
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.
111
112 Subdirectory templates `.sd.mk' vs plain autoconf templates `.mk.in'
113 --------------------------------------------------------------------
114
115 There are two kinds of template files.
116
117  Filename                 .sd.mk                  .mk.in
118
119  Processed by             &-substitution,         autoconf only
120                           then autoconf
121
122  Instantiated             Usu. once per subdir    Once only
123
124  Need to be mentioned     No, but Subdir.sd.mk    All not in subdirmk/
125  in configure.ac?         via SUBDIRMK_SUBDIRS    via SUBDIRMK_MAKEFILES
126
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
130                            Subdir and Perdir)
131
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.
135
136 Substitution syntax
137 -------------------
138
139 In general & expands to the subdirectory name when used for a
140 filename, and to the subdirectory name with / replaced with _ for
141 variable names.
142
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.
147
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
152 empty string).
153
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:
159
160 &_              =>      sub_dir_                        or TOP_
161 &/              =>      sub/dir/                        or nothing
162 &=_             =>      sub_dir                         or TOP
163 &=/             =>      sub/dir                         or .
164 &^              =>      $(top_srcdir)/sub/dir           or $(top_srcdir)
165 &~              =>      $(abs_top_srcdir)/sub/dir       or $(abs_top_srcdir)
166
167 &&              =>      &&              for convenience in shell runes
168 \&              =>      &               general escaping mechanism
169
170 & thing thing... &
171 & ^ thing thing... &
172 & ~ thing thing... &
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.
179
180 &:<directive> <args>....
181         recognised at start of line only (possibly after lwsp)
182         args are processed for &
183
184 &:include filename              filename should usually be foo.sd.mk
185 &:-include filename             tolerate nonexistent file
186
187 &!<lwsp>        disables & until EOL (and then disappears)
188
189 &!STUFF
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
193         are discarded.
194
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.
199
200         Notably
201                 STUFFSTUFF      =>      STUFFSTUFF
202                 \STUFF          =>      STUFF
203                 STUFF!&         set escape back to &
204
205 &TARGETS_things
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)
210
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
214
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'.
219
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.
223
224         `all' is extra special: every directory has an `all'
225         target, which corresponds to &TARGETS.
226
227 Subdirectory and variable naming
228 --------------------------------
229
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.
233
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.
238
239 If you name your variables in ALL CAPS and your subdirectories in
240 lower case with `-' rather than `_', there will be no confusion.
241
242 Incorporating this into your project
243 ------------------------------------
244
245 Use `git-subtree' to merge the subdirmk/ directory.  You may find it
246 useful to symlink the DEVELOPER-CERTIFICATE file (git can store
247 symlinks as symlinks - just `git add' the link).  And you probably
248 want to mention the situation in your top-level COPYING.
249
250 Symlink autogen.sh into your project toplevel.
251
252 In your configure.ac, say
253
254   m4_include([subdirmk/subdirmk.ac])
255   SUBDIRMK_SUBDIRS([...list of subdirectories in relative syntax...])
256
257 Write a Subdir.sd.mk in each directory.  The toplevel one should
258 probably contain:
259
260   include subdirmk/usual.mk
261   include subdirmk/regen.mk
262
263 Write a Perdir.sd.mk in the toplevel, if you want.  It should probably
264 have:
265
266   &:include subdirmk/cdeps.sd.mk
267   &:include subdirmk/clean.sd.mk
268
269
270 Legal information
271 -----------------
272
273 subdirmk is
274  Copyright 2019 Mark Wooding
275  Copyright 2019 Ian Jackson
276
277     subdirmk and its example is free software; you can redistribute it
278     and/or modify it under the terms of the GNU Library General Public
279     License as published by the Free Software Foundation; either
280     version 2 of the License, or (at your option) any later version.
281
282     This is distributed in the hope that it will be useful, but
283     WITHOUT ANY WARRANTY; without even the implied warranty of
284     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
285     Library General Public License for more details.
286
287     You should have received a copy of the GNU Library General Public
288     License along with this library as the file LGPL-2.
289     If not, see https://www.gnu.org/.
290
291 Individual files generally contain the following tag in the copyright
292 notice, instead of the full licence grant text:
293   SPDX-License-Identifier: LGPL-2.0-or-later
294 As is conventional, this should be read as a licence grant.
295
296 Contributions are accepted based on the git commit Signed-off-by
297 convention, by which the contributors' certify their contributions
298 according to the Developer Certificate of Origin version 1.1 - see
299 the file DEVELOPER-CERTIFICATE.
300
301 Where subdirmk is used by and incorporated into another project (eg
302 via git subtree), the directory subdirmk/ is under GNU LGPL-2.0+, and
303 the rest of the project are under that other project's licence(s).
304 (The project's overall licence must be compatible with LGPL-2.0+.)