The developer is expected to write a makefile fragment, in each
relevant subdirectory, called `Subdir.sd.mk'.
-These fragments may contain ordinary make language.
+These fragments may contain ordinary make language. Unqualified
+filenames are relative to the build toplevel, and all commands all run
+there.
However, the sigil & is treated specially. By and large, it refers to
-`the current directory'. There are a variety of convenient
-constructions.
+`the build directory corresponding to this .sd.mk file', etc.
+There are a variety of convenient constructions.
The result is that to a large extent, the Subdir.sd.mk has an easy way
to namespace its "local" make variables, and an easy way to refer to
-its "local" filenames.
+its "local" filenames (and filenames in general).
The Subdir.sd.mk's are filtered, fed through autoconf in the usual way
(for @..@-substitutions) and included by one autogenerated toplevel
&:include subdirmk/clean.sd.mk
For example you could put that in Perdir.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.
+
+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
------------------
automatic regeneration for all of this template substitution, and for
config.status etc. is done for you.
-Summary of recommended directory reference syntaxes
----------------------------------------------------
+Tables of file reference syntaxes
+---------------------------------
+
+In a nonrecursive makefile supporting out of tree builds there are
+three separate important distinctions between different file
+locations:
+
+ (i) In the build tree, or in the source tree ?
+
+ (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. Where an absolute pathname is needed, it can be built
+ out of &/ and an appropriate make variable such as $(PWD).
-Path construction &-expansions, meanings summary:
+Path construction &-expansions are built from the following:
- In build tree In source tree
- This directory just & &,
- Top level &. implies absolute &;
+ Relative paths in...
+ build source
+
+ This directory & &^
+ Top level . &~
-Adding `@' means "absolute path". This is not needed with &. because
-there is never any need to use &. since it would expand to nothing.
-`/' terminates the escape (needed if the next thing is not a lowercase
-character, or space). `=' means "just the value, no /". Space starts
-multi-word processing.
+In more detail, with all the various options laid out:
- Recommended In build tree In source tree
- when Relative Absolute Relative Absolute
-
- 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
+ Recommended Relative paths in... Absolute paths in...
+ for build source build source
+
+ 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
+ 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...)
- Top lc &.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 $(abs)/file $(src)/file $(abs_src)/file
+(This assumes you have appropriate make variables src, PWD and
+abs_src.)
Substitution syntax
-------------------
-In general & expands to the subdirectory name when used for a
-filename, and to the subdirectory name with / replaced with _ for
-variable names.
+In general & expands to the subdirectory name. (`/' is legal in make
+variable names.)
Note that & is processed *even in makefile comments*. The substitutor
does not understand make syntax, or shell syntax, at all. However,
In the notation below, we suppose that the substitution is being in
done in a subdirectory sub/dir of the source tree. In the RH column
we describe the expansion at the top level, which is often a special
-case (in general in variable names we call that TOP rather than the
-empty string).
+case. (Even in variable names: top level's start `./'.)
-&CAPS => sub_dir_CAPS or TOP_CAPS
-&lc => sub/dir/lc or lc
- Here CAPS is any ASCII letter A-Z and lc is a-z.
- The assumption is that filenames are usually lowercase and
- variables usually uppercase. Otherwise, use another syntax:
-
-&_ => sub_dir_ or TOP_
-&=_ => sub_dir or TOP
+&alpha => sub/dir/alpha or ./alpha
+ Here alpha is any ASCII letter A-Za-z.
+ The assumption is that filenames and variables usually
+ start with a letter. Otherwise, use another syntax:
&/ => sub/dir/ or nothing
-&=/ => sub/dir or .
-
-&,lc => $(top_srcdir)/sub/dir/lc
-&,/ => $(top_srcdir)/sub/dir/
-
-&;lc => $(top_srcdir)/sub/dir/lc
-&;/ => $(top_srcdir)/sub/dir/
+&. => sub/dir or .
+ (This implies that `&./' works much like `&/'. &./ is
+ suitable for variable name construction in a way &/ is not.)
-&@lc => $(PWD)/sub/dir/lc
-&@/ => $(PWD)/sub/dir/
+&^alpha => $(top_srcdir)/sub/dir/alpha
+&^/ => $(top_srcdir)/sub/dir/
+&^. => $(top_srcdir)/sub/dir
-&.lc => $(PWD)/lc
-&./ => $(PWD)/
-
-&@,lc => $(abs_top_srcdir)/sub/dir/lc
-&@,/ => $(abs_top_srcdir)/sub/dir/
-
-&@;lc => $(abs_top_srcdir)/sub/dir/lc
-&@;/ => $(abs_top_srcdir)/sub/dir/
+&~alpha => $(top_srcdir)/alpha
+&~/ => $(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, implies absolute pathnames
- @ absolute pathnames (forbidden with `.', must come first)
+ ^ pathname of this subdirectory in source tree
+ ~ pathname of top level of source tree
+ / terminates the escape (needed if next is not lwsp, alpha or `.')
+ . terminates the escape, gives subdir without /
+ lwsp starts multi-word processing (see below)
-So pathname syntax is a subset of:
- '&' [ '@' ] [ ',' | ';' | '.' ] [ lc | '/' ]
+&_ => ERROR (for compat with v1)
- To avoid incomprehensible .sd.mk files, some combinations are not
- allowed. For example `&@=./' would mean `$(PWD)/sub/dir' but can
- be spelled `$(PWD)/&=/', but more normally the trailing / can be
- tolerated, so use `&@/'.
+So pathname and variable syntax is a subset of:
+ '&' [ '^' | '~' ] [ alpha... | '/' | '.' ]
&& => && for convenience in shell runes
-\& => & general escaping mechanism
+&@ => & general escaping mechanism
+&&@ => && @ after any number of & vanishes
+
+&$VARIABLE $(sub/dir/VARIABLE)
+ VARIABLE is ASCII starting with a letter and matching \w+
-& thing thing... &
-&. thing thing... & &@. thing thing... &
-&, thing thing... & &@, thing thing... &
-&; thing thing... & &@; thing thing... &
+& thing thing... &
+&/ 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 &/ &./ &@./
+ Introduced by &... followed by lwsp where alpha could go.
+ Each lwsp-separated non-ws word is prefixed by &/ etc.
etc. respectively. No other & escapes are recognised.
This processing continues until & preceded by lwsp,
or until EOL (the end of the line), or \ then EOL.
&:-include filename tolerate nonexistent file
filenames are relative to $(top_srcdir)
+&:section number [ident]
+ Sections will be read by make in order, first by number
+ and only then by input file (in order passed
+ to generate ie that specified in configure.ac).
+ Number is \d+; order is lexical.
+ Default section number is `5'.
+ Section numbers may not contain only `0'.
+ Section is local to &:include'd files (reset to `5'
+ on entry, restored on return).
+ Ident is [A-Za-z][A-Z0-9a-z/_-]+ and is currently unused,
+ other than appearing in output. When used, will default
+ to source-relative input file name excluding .sd.mk.
+
&!<lwsp> disables & until EOL (and then disappears)
&# delete everything to end of line
(useful if the RHS contains unrecognised & constructions)
-&!STUFF
+&:changequote 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.
+ and is terminated by EOL or lwsp. The whole line is
+ discarded.
After this, write STUFF instead of &, everywhere.
The effect is global and lasts until the next setting.
it back before using &:include.
Notably
- STUFFSTUFF => STUFFSTUFF
- \STUFF => STUFF
- STUFF!& set escape back to &
+ STUFFSTUFF => STUFFSTUFF
+ STUFF@ => STUFF
+ STUFF: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)
arranges that the *parent* will also have a `things' target
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.
+ Must be spelled exactly &TARGETS_things. &/TARGETS_things,
+ 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.
+DRAFT - MACRO ASSISTANCE FACILITY
+---------------------------------
+
+Thanks to Mark Wooding.
+
+ &:macro NAME
+ STUFF
+ &:endm
+
+expands to
+
+ define %NAME
+ STUFF (with `$'s doubled except before a digit)
+ endef
+ NAME = $(eval $(call %NAME,$1,$2,$3,$4,$5,$6,$7,$8,$9))
+
+and
+
+ &(NAME ARG,ARG,...)
+
+expands to
+
+ $(call NAME,ARG,ARG,...)
+
+with `$'s doubled.
+
Subdirectory and variable naming
--------------------------------
subdirectory names, and parts that mean something else.
So it is a good idea to be a bit careful with your directory naming.
-`TOP', names that contain `_', and names that are similar to parts of
+`.', names that contain `/', and names that are similar to parts of
make variables (whether conventional ones, or ones used in your
project) are best avoided.
-If you name your variables in ALL CAPS and your subdirectories in
-lower case with `-' rather than `_', there will be no confusion.
-
Incorporating this into your project
------------------------------------