`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).
+builds well, and helps a bit with metaprogramming and rule writing).
Basic approach
--------------
In general & expands to the subdirectory name when used for a
filename, and to the subdirectory name with / replaced with _ for
-variable names.
+variable names. (If your variables start with capital letters and
+your filenames with lowercase. Otherwise, use &/ or &_.)
Note that & is processed *even in makefile comments*. The substitutor
does not understand make syntax, or shell syntax, at all. However,
^ pathname of this subdirectory in source tree
~ pathname of top level of source tree
/ terminates the path escape } needed if next is
- _ terminates the var escape } not lwsp or space)
+ _ terminates the var escape } not letter or space)
. terminates path escape giving dir name (excluding /)
= terminates var escape giving only prefix part (rarely needed)
lwsp starts multi-word processing (see below)
So pathname syntax is a subset of:
- '&' [ '^' | '~' ] [ lc | '/' | '.' | '=' ]
+ '&' [ '^' | '~' ] [ lc | '/' | '.' ]
&& => && for convenience in shell runes
&:include filename filename should usually be [&]foo.sd.mk
&:-include filename tolerate nonexistent file
- filenames are relative to $(top_srcdir)
- RHS is &-expanded
+ RHS is &-expanded but filenames are relative to the top
+ srcdir. This implies that unqualified names are like &~/
+ whereas &/ is like &^/. &^ and &~ do not work here because
+ they expand to constructions involving literally
+ `$(top_srcdir)', but the RHS is not make-expanded.
&!<lwsp> disables & until EOL (and then disappears)
&# delete everything to end of line
(useful if the RHS contains unrecognised & constructions)
-&:changequote NEWQUOTE
- changes the escape sequence from & to literally NEWQUOTE
- NEWQUOTE may be any series of of non-whitespace characters,
- and is terminated by EOL or lwsp. The whole line is
- discarded.
-
- After this, write NEWQUOTE instead of &, everywhere.
- The effect is global and lasts until the next setting.
- It takes effect on &:include'd files too, so maybe set
- it back before using &:include.
-
- Notably
- NEWQUOTENEWQUOTE => NEWQUOTENEWQUOTE
- NEWQUOTE\NEWQUOTE => NEWQUOTE
- NEWQUOTE\$ => $
- NEWQUOTE:changequote & set escape back to &
-
&TARGETS_things
Handled specially. If mentioned at the start of a line
(possibly following whitespace), declares that this
`all' is extra special: every directory has an `all'
target, which corresponds to &TARGETS.
+&:warn [!]WARNTAG ...
+ Suppress (with !) or re-enable (without !) warnings tagged
+ WARNTAG (see section `Warnings', below). The suppression list
+ is reset at the start of processing in each subdirectory.
+ Warnings that appear at the end of processing are controlled
+ by the final warning state after processing all the toplevel
+ input files (including Final.sd.mk).
+
+&:local+global [&]VARIABLE ...
+ Suppresses the warning about seeing both VARIABLE and
+ &VARIABLE. Any & specified in the RHS is redundant: this
+ always affects both versions identically.
+
+&:changequote NEWQUOTE
+ changes the escape sequence from & to literally NEWQUOTE
+ NEWQUOTE may be any series of of non-whitespace characters,
+ and is terminated by EOL or lwsp. The whole line is
+ discarded.
+
+ After this, write NEWQUOTE instead of &, everywhere.
+ The effect is unscoped and lasts until the next setting,
+ or until the end of the current directory's Suffix.sd.mk.
+ It takes effect on &:include'd files too, so maybe set
+ it back before using &:include.
+
+ Notably
+ NEWQUOTENEWQUOTE => NEWQUOTENEWQUOTE
+ NEWQUOTE\NEWQUOTE => NEWQUOTE
+ NEWQUOTE\$ => $
+ NEWQUOTE:changequote & set escape back to &
+
Dollar doubling and macro assistance
------------------------------------
&$NN => $(NN) where N are digits
&$( => $(
+A few contexts do not support $-doubling, such as directive arguments
+or places where this might imply $-quadrupling. (There is no way to
+get $-quadrupling.)
+
Tables of file reference syntaxes
---------------------------------
(This assumes you have appropriate make variables src, PWD and
abs_src.)
+Warnings
+--------
+
+subdirmk's `generate' program, which does the acual &-substitution,
+can produce some warnings about your .sd.mk files. These can be
+suppressed with the &:warn directive. The warning tags are:
+
+ local+global
+ The same VARNAME was used both with and without an & prefix.
+ This can be confusing. Also, if you avoid this then you will
+ get a warning iff you accidentally leave off a needed &.
+ (You can suppress this warning for a particular VARNAME with
+ the &:local+global directive.)
+
+ single-char-var
+ A variable expansion like $FBAR. make's expansion rules
+ interpret this as $(F)BAR. It's normally better to write
+ it this way, at least if the variable expansion is followed
+ by more letters. Note that &$FOO works differently to
+ raw make: it expands to $(sub_dir_FOO).
+
+ unknown-warning
+ &:warn was used to try to enable a warning that this version
+ of subdirmk does not understand. (Note that an attempt to
+ *dis*able an unknown warning is only reported if some other
+ warning was issued which might have been disabled.)
+
Subdirectory and variable naming
--------------------------------
Use `git-subtree' to merge the subdirmk/ directory. You may find it
useful to symlink the DEVELOPER-CERTIFICATE file (git can store
symlinks as symlinks - just `git add' the link). And you probably
-want to mention the situation in your top-level COPYING.
+want to mention the situation in your top-level COPYING and HACKING.
Symlink autogen.sh into your project toplevel.
stuff to configure.ac, and fix everything up. Leave the existing
$(MAKE) -C for your existing subdirectories alone. Then you can
convert individual subdirectories, or classes of subdirectories, at
-your leisure. (You must be /sure/ that each subdirectory will be
-entered only once at a time, but your existing recursive make descent
-system should already do that or you already have concurrency bugs.)
+your leisure. (You must be /sure/ that each recursive (non-subdirmk)
+subdirectory will be entered only once at a time, but your existing
+recursive make descent system should already do that or you already
+have concurrency bugs.)
Aside from this, be very wary of any invocation of $(MAKE) anywhere.
This is a frequent source of concurrency bugs in recursive make build