chiark / gitweb /
e6da9eecd1f68b68ab930560236e802a741fb3cf
[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         is 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      =>      STUFF
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.