at a time. There is no sequencing between subdirectories, only been
individual targets (as specified according to their dependencies).
-You can define other per-directory recursive targets too: simply
-mention (usually, by setting) the variable &TARGETS_zonk, or whatever.
-This will create a src/zonk target (for appropriate value of src/).
-Unlike `all', these other targets only exist in areas of the project
-where at least something mentions them. So for example, if
-&TARGETS_zonk is mentioned in src but not lib, `make zonk' in
-lib will fail. If you want to make a target exist everywhere,
-mention its name in Perdir.sd.mk (see below).
-
-Perdir.sd.mk, inclusion
------------------------
-
-The file Perdir.sd.mk in the toplevel of the source is automatically
-processed after each individual directory's Subdir.sd.mk, and the
-&-substituted contents therefore appear once for each subdirectory.
+You can define other per-directory recursive targets too: set the
+variable &TARGETS_zonk, or whatever (being sure to write &TARGETS_zonk
+at the start of a line). This will create a src/zonk target (for
+appropriate value of src/). Unlike `all', these other targets only
+exist in areas of the project where at least something mentions them.
+So for example, if &TARGETS_zonk is set in src but not lib, `make
+zonk' in lib will fail. If you want to make a target exist
+everywhere, += it with nothing in Prefix.sd.mk or Suffix.sd.mk (see
+below).
+
+Prefix.sd.mk, Suffix.sd.mk, Final.sd.mk, inclusion
+--------------------------------------------------
+
+The files Prefix.sd.mk and Suffix.sd.mk in the toplevel of the source
+are automatically processed before and after each individual
+directory's Subdir.sd.mk, and the &-substituted contents therefore
+appear once for each subdirectory.
This lets you do per-directory boilerplate. Some useful boilerplate
is already provided in subdirmk, for you to reference like this:
&:include subdirmk/cdeps.sd.mk
&:include subdirmk/clean.sd.mk
-For example you could put that in Perdir.sd.mk.
+For example you could put that in Suffix.sd.mk.
+
+The top-level Subdir.sd.mk is the first makefile included after the
+autogenerated `main.mk' which merely has some basic settings and
+includes. So if you want to get in early and set global variables,
+put them near the top of Subdir.sd.mk.
+
+The file Final.sd.mk in the toplevel directory is processed and
+included after all the other files.
+
+subdirmk's filter script itself sets (only) these variables:
+ top_srcdir
+ abs_top_srcdir
+ SUBDIRMK_MAKEFILES
+ MAKEFILE_TEMPLATES
+You are likely to want to define $(PWD), and shorter names for
+top_srdir and abs_top_srcdir (we suggest $(src) and $(abs_src)).
Global definitions
------------------
How to include `&:include foo.sd.mk' `include foo.mk'
in all relevant .sd.mk in only one
(but not needed for Subdir.sd.mk
- Subdir and Perdir)
+ Prefix, Suffix, Final)
If you `include subdirmk/regen.mk', dependency management and
automatic regeneration for all of this template substitution, and for
(ii) In (or relative to) the subdirectory to which this Subdir.sd.mk
relates, or relative to the project's top level ?
- (iii) Absolute or relative pathname ?
- (Usually relative pathnames suffice.)
+ (iii) Absolute or relative pathname ? Usually relative pathnames
+ suffice. Where an absolute pathname is needed, it can be built
+ out of &/ and an appropriate make variable such as $(PWD).
Path construction &-expansions are built from the following:
- Relative paths in... Absolute paths in...
- build source build source
+ Relative paths in...
+ build source
- This directory & &, &@ &@,
- Top level . &; &@. &@;
+ This directory & &^
+ Top level . &~
-In more detail, with the various options for what comes next:
+In more detail, with all the various options laid out:
Recommended Relative paths in... Absolute paths in...
- for build source build source
+ for build source build source
- This lc &file &,file &@file &@,file
- directory any &/file &,/file &@/file &@,/file
- several & f g h &, f g h &@ f g h &@, f g h
+ This lc &file &^file $(PWD)/&file $(abs_src)/&file
+ directory any &/file &^/file $(PWD)/&/file $(abs_src)/&/file
+ several & f g h &^ f g h $(addprefix...)
- Top lc file &;file &@.file &@;file
- level any file &;/file &@./file &@;/file
- several f g h &; f g h &@. f g h &@; f g h
- .mk.in file $(src)/file $(abs)/file $(abs_src)/file
+ Top lc file &~file
+ level any file &~/file $(PWD)/file $(abs_src)/file
+ .mk.in file $(src)/file $(PWD)/file $(abs_src)/file
+ several f g h &~ f g h $(addprefix...)
+
+(This assumes you have appropriate make variables src, PWD and
+abs_src.)
Substitution syntax
-------------------
The assumption is that filenames are usually lowercase and
variables usually uppercase. Otherwise, use another syntax:
+&/ => sub/dir/ or nothing
&_ => sub_dir_ or TOP_
-&=_ => sub_dir or TOP
+&. => sub/dir or .
+ (This implies that `&./' works roughly like `&/', although
+ it can produce a needless `./')
-&/ => sub/dir/ or nothing
-&=/ => sub/dir or .
+&= => sub_dir or TOP
-&,lc => $(top_srcdir)/sub/dir/lc &,/ => $(top_srcdir)/sub/dir/
-&;lc => $(top_srcdir)/lc &;/ => $(top_srcdir)/
+&^lc => $(top_srcdir)/sub/dir/lc
+&^/ => $(top_srcdir)/sub/dir/
+&^. => $(top_srcdir)/sub/dir
-&@lc => $(PWD)/sub/dir/lc &@/ => $(PWD)/sub/dir/
-&@.lc => $(PWD)/lc &@./ => $(PWD)/
-&@,lc => $(abs_top_srcdir)/sub/dir/lc &@,/ => $(abs_top_srcdir)/sub/dir/
-&@;lc => $(abs_top_srcdir)/lc &@;/ => $(abs_top_srcdir)/
+&~lc => $(top_srcdir)/lc
+&~/ => $(top_srcdir)/
+&~. => $(top_srcdir)
In general:
- = return subdir without delimiter (not allowed with `,' `;' `@')
- , pathname of this subdirectory in source tree
- ; pathname of top level of source tree
- . pathname of this directory in build tree, `@' must be specified
- @ absolute pathnames
- / terminates the escape (needed if next is not lwsp or space)
+ ^ 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 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 | '/' ]
-
- To avoid incomprehensible .sd.mk files, some combinations are not
- allowed. For example `&=./' would mean `.' and `&./' would be the
- empty string. Variations with `=' and one of `@' `,' `;' are
- uncommon and must be written using make variables instead.
+ '&' [ '^' | '~' ] [ lc | '/' | '.' | '=' ]
&& => && for convenience in shell runes
-\& => & general escaping mechanism
-& thing thing... & &@ thing thing... &
- &. thing thing... &
-&, thing thing... & &@, thing thing... &
-&; thing thing... & &@; thing thing... &
+&\& => & general escaping mechanism
+&\$ => $ provided for $-doubling regimes
+&\NEWLINE eats the newline and vanishes
+
+&$VARIABLE => $(sub_dir_VARIABLE) or $(TOP_VARIABLE)
+ VARIABLE is ASCII starting with a letter and matching \w+
+
+& thing thing... &
+&^ thing thing... &
+&~ thing thing... &
Convenience syntax for prefixing multiple filenames.
Introduced by & followed by lwsp where lc could go.
Each lwsp-separated non-ws word is prefixed by &/ etc.
&:<directive> <args>....
recognised at start of line only (possibly after lwsp)
- args are processed for &
-&:include filename filename should usually be foo.sd.mk
+&:include filename filename should usually be [&]foo.sd.mk
&:-include filename tolerate nonexistent file
filenames are relative to $(top_srcdir)
+ RHS is &-expanded
&!<lwsp> disables & until EOL (and then disappears)
&# delete everything to end of line
(useful if the RHS contains unrecognised & constructions)
-&!STUFF
- changes the escape sequence from & to literally STUFF
- STUFF may be any series of of non-whitespace characters,
- and is terminated by EOL or lwsp. &!STUFF and the lwsp
- are discarded.
+&: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 STUFF instead of &, everywhere.
+ 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
- STUFFSTUFF => STUFFSTUFF
- \STUFF => STUFF
- STUFF!& set escape back to &
+ NEWQUOTENEWQUOTE => NEWQUOTENEWQUOTE
+ NEWQUOTE\NEWQUOTE => NEWQUOTE
+ NEWQUOTE\$ => $
+ NEWQUOTE:changequote & set escape back to &
&TARGETS_things
- Handled specially. If mentioned, declares that this
+ Handled specially. If mentioned at the start of a line
+ (possibly following whitespace), declares that this
subdir ought to have a target `things'. The rule will be
&/things:: $(&TARGETS_things)
which recursively implies this directory's `things'.
Must be spelled exactly &TARGETS_things. &_TARGETS_things,
- for example, is not magic. But mentioning &TARGETS_things in
- a #-comment *does* work because the & filter does not care
- about comments.
+ for example, is not magic. To make the target exist
+ without providing any prerequisites for it, write a line
+ containing just `&TARGETS_things +='.
`all' is extra special: every directory has an `all'
target, which corresponds to &TARGETS.
+
+Dollar doubling and macro assistance
+------------------------------------
+
+&$+ Starts dollar-doubling
+&$- Stops dollar-doubling
+ Both are idempotent and local to the file or context.
+
+Sometimes we will show $'s being doubled inside another construct.
+This means the content of the construct is $-doubled: $-doubling is
+locally enabled, and restored afterwards.
+
+&:macro NAME => define NAME
+STUFF $ THINGS .. STUFF $$ THINGS
+&:endm .. endef
+ NAME is processed for &
+
+While dollar-doubling:
+- - - - - - - - - - -
+
+$ => $$ including $'s produced by other
+ &-expansions not mentioned here
+
+&\$ => $
+&$NN => $(NN) where N are digits
+&$( => $(
+
+
Subdirectory and variable naming
--------------------------------
include subdirmk/usual.mk
include subdirmk/regen.mk
-Write a Perdir.sd.mk in the toplevel, if you want. It should probably
+Write a Suffix.sd.mk in the toplevel, if you want. It should probably
have:
&:include subdirmk/cdeps.sd.mk
far enough to regenerate a working set of makefiles. If this happens
just rerun ./config.status by hand.
+If you go back and forth between different versions of your code you
+can sometimes find that `make' complains that one of your Subdir.sd.mk
+files is missing: typically, if iot was used and therefore a
+dependency in some other version of your code. If you run `make
+clean' (or `make realclean') these dependencies are suppressed, which
+will clear up the problem.
+
Legal information
-----------------