&= => sub_dir or TOP
-&^lc => $(top_srcdir)/sub/dir/lc
-&^/ => $(top_srcdir)/sub/dir/
-&^. => $(top_srcdir)/sub/dir
+&^lc => ${top_srcdir}/sub/dir/lc
+&^/ => ${top_srcdir}/sub/dir/
+&^. => ${top_srcdir}/sub/dir
-&~lc => $(top_srcdir)/lc
-&~/ => $(top_srcdir)/
-&~. => $(top_srcdir)
+&~lc => ${top_srcdir}/lc
+&~/ => ${top_srcdir}/
+&~. => ${top_srcdir}
In general:
^ pathname of this subdirectory in source tree
&\$ => $ provided for $-doubling regimes
&\NEWLINE eats the newline and vanishes
-&$VARIABLE => $(sub_dir_VARIABLE) or $(TOP_VARIABLE)
+&$VARIABLE => ${sub_dir_VARIABLE} or ${TOP_VARIABLE}
VARIABLE is ASCII starting with a letter and matching \w+
& thing thing... &
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.
+&:local+global [!][&]VARIABLE ...
+ Suppresses any warnings relating to forthcoming mentions
+ to VARIABLE or &VARIABLE, as applicable. Scope ends at
+ the end of the current directory's Suffix.sd.mk.
+ Prefixing with ! removes [&]VARIABLE from the suppresion list.
&:changequote NEWQUOTE
changes the escape sequence from & to literally NEWQUOTE
&$- Stops dollar-doubling
Both are idempotent and local to the file or context.
+This is useful both for make macrology involving $(eval ...), and
+possibly for helping write complicated recipes involving shell
+variables, inline Perl code, etc.
+
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.
&:endm .. endef
NAME is processed for &
-&${..$..} => ${eval ${call ..$$..}}
+&{..$..} => ${eval ${call ..$$..}}
(matches { } pairs to find the end)
content is $-doubled (unless it contains &$- to turn that off)
+ cf &(...), see "Convenience syntax for eval", below.
Together &:macro and &${...} provide a more reasonable macro facility
than raw make. They solve the problem that make expansions cannot
&-expansions not mentioned here
&\$ => $
-&$NN => $(NN) where N are digits
-&$( => $(
+&$( => ${ (expands to { } so it is useable for shell too)
+&$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.)
+Convenience syntax for eval
+- - - - - - - - - - - - - -
+
+&(thing => $(call thing
+&( thing => $(call thing
+ and specially:
+&(&lc => $(call sub_dir_lc or $(call TOP_lc
+&( &lc => $(call sub_dir_lc or $(call TOP_lc
+ even though lc would normally be thought a filename
+
+Unlike &{...}, this does not involve any dollar-doubling.
+
Invocation, "recursive" per-directory targets
---------------------------------------------
You are likely to want to define $(PWD), and shorter names for
top_srdir and abs_top_srcdir (we suggest $(src) 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 &.
+ The generation of this warning depends on scanning your
+ makefile for things that look like variable references, which
+ subdirmk does not do completely perfectly. Exciting make
+ syntax may evade this warning, or require suppressions.
+ (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}.
+
+ broken-var-ref
+ An attempt at variable expansion looking like $&...
+ You probably expected this to mean $(TOP_F)BAR but it
+ expands to $TOP_FBAR which make thinks means $(T)OP_FBAR.
+
+ 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.)
+
+
+Guides, hints, and further explanations
+=======================================
+
+Incorporating this into your project
+------------------------------------
+
+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 and HACKING.
+
+Symlink autogen.sh into your project toplevel.
+
+In your configure.ac, say
+
+ m4_include([subdirmk/subdirmk.ac])
+ SUBDIRMK_SUBDIRS([...list of subdirectories in relative syntax...])
+
+Write a Dir.sd.mk in each directory. See the substitution syntax
+reference, above, and the example/ directory here. The toplevel
+Dir.sd.mk should probably contain:
+
+ include subdirmk/usual.mk
+ include subdirmk/regen.mk
+
+Write a Suffix.sd.mk in the toplevel, if you want. It should probably
+have:
+
+ &:include subdirmk/cdeps.sd.mk
+ &:include subdirmk/clean.sd.mk
+
+
+Hints
+-----
+
+You can convert your project incrementally. Start with the top-level
+Makefile.in and rename it to Dir.sd.mk, and add the appropriate
+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 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
+systems. When combined with nonrecursive make it's all in the same
+directory and there is nothing stopping the different invocations
+ending up trying to make the same targets at the same time. That
+causes hideous racy lossage. There are ways to get this to work
+reliably but it is advanced stuff.
+
+If you make syntax errors, or certain kinds of other errors, in your
+makefiles, you may find that just `make' is broken now and cannot get
+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 Dir.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.
+
+
Global definitions
------------------
subdirectories, you should probably do that with target-specific
variable settings. See the info node `(make) Target-specific'.
+
Directory templates `.sd.mk' vs plain autoconf templates `.mk.in'
--------------------------------------------------------------------
(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 &.
- The generation of this warning depends on scanning your
- makefile for things that look like variable references, which
- subdirmk does not do completely perfectly. Exciting make
- syntax may evade this warning, or require suppressions.
- (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
--------------------------------
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
-------------------------------------
-
-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 and HACKING.
-
-Symlink autogen.sh into your project toplevel.
-
-In your configure.ac, say
-
- m4_include([subdirmk/subdirmk.ac])
- SUBDIRMK_SUBDIRS([...list of subdirectories in relative syntax...])
-
-Write a Dir.sd.mk in each directory. The toplevel one should
-probably contain:
-
- include subdirmk/usual.mk
- include subdirmk/regen.mk
-
-Write a Suffix.sd.mk in the toplevel, if you want. It should probably
-have:
-
- &:include subdirmk/cdeps.sd.mk
- &:include subdirmk/clean.sd.mk
-
-Hints
------
-
-You can convert your project incrementally. Start with the top-level
-Makefile.in and rename it to Dir.sd.mk, and add the appropriate
-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 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
-systems. When combined with nonrecursive make it's all in the same
-directory and there is nothing stopping the different invocations
-ending up trying to make the same targets at the same time. That
-causes hideous racy lossage. There are ways to get this to work
-reliably but it is advanced stuff.
-
-If you make syntax errors, or certain kinds of other errors, in your
-makefiles, you may find that just `make' is broken now and cannot get
-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
------------------
+=================
subdirmk is
Copyright 2019 Mark Wooding