subdirmk - assistance for non-recursive use of make =================================================== Introduction ------------ Peter Miller's 1997 essay _Recursive Make Considered Harmful_ persuasively argues that it is better to arrannge to have a single make invocation with the project's complete dependency tree, rather than the currently conventional `$(MAKE) -C subdirectory' approach. However, actually writing a project's build system in a non-recursive style is not very ergonomic. The main difficulties are: - constantly having to write out long file and directory names - the lack of a per-directory make variable namespace means long make variables (or namespace clashes) - it is difficult to arrange that one can cd to a subdirectory and say `make all' and have something reasonable happen (to wit, build an appropriate subset) `subdirmk' is an attempt to solve these problems (and it also slightly alleviates some of the boilerplate needed to support out-of-tree builds well). Basic approach -------------- The developer is expected to write a makefile fragment in each relevant subdirectory called `Subdir.mk.in'. These fragments may contain ordinary make language. However, the sigil & is treated specially. By and large, it refers to `the current directory'. Variable names and filenames may be prefixed by &_ and &/. Lists of https://web.archive.org/web/20150330111905/http://miller.emu.id.au/pmiller/books/rmch/ &CAPS => subdir_CAPS or TOP_CAPS &lc => subdir/lc or lc &_ => subdir_ or TOP_ &/ => subdir/ or nothing &=_ => subdir or TOP &=/ => subdir or . &^ => $(top_srcdir)/subdir or $(top_srcdir) &~ => $(abs_top_srcdir)/subdir or $(abs_top_srcdir) && => && \& => & & thing thing... & => each thing prefixed by &/ &^/ &~/ resp & ^ thing thing... & each thing is any non-ws & ~ thing thing... & & may be omitted before EOL or before \EOL other &'s not recognised start of line (maybe after ws): &: .... args are processed for & first &:include filename filename should usually be foo.mk.in &:-include filename CAPS is [A-Z][0-9_A-Z]*(?!\w) lc is [a-z][-+,0-9_a-z]*(?!\w) &! disables & *until* EOL (and disappears) &!STUFF STUFF is recognised instead of & the terminating lwsp is discarded too may also occur at eol eg notably STUFF!& now & is recognised instead (ie back to normal) STUFFSTUFF STUFF eg &!@@@ @@@ is recognised instead of & @@@!& go back to & &TARGETS[_things] is handled specially must be spelled precisely this way if no _things, means _all Also, `all' is weird in that it is present even if not specified