Where there are dependencies between subdirectories, each Dir.sd.mk
can simply refer to files in other subdirectories directly.
-Invocation, "recursive" per-directory targets
----------------------------------------------
-
-Arrangements are made so that when you run `make foo' in a
-subdirectory, it is like running the whole toplevel makefile, from the
-toplevel, as `make subdir/foo'. If `subdir/foo' is a file that might
-be built, that builds it.
-
-But `foo' can also be a conventional target like `all'.
-
-Each subdirectory has its own `all' target. For example a
-subdirectory `src' has a target `src/all'. The rules for these are
-automatically generated from the settings of the per-directory
-&TARGETS variables. &TARGETS is magic in this way. (In
-src/Dir.sd.mk, &TARGETS of course refers to a make variable called
-src_TARGETS.)
-
-The `all' target in a parent directory is taken to imply the `all'
-targets in all of its subdirectories, recursively. And in the
-autogenerated stub Makefiles, `all' is the default target. So if you
-just type `make' in the toplevel, you are asking for `&all'
-(<subdir>/all) for every directory in the project.
-
-In a parallel build, the rules for all these various subdirectory
-targets may be in run in parallel: there is only one `make' invocation
-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: 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 Dir.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 Suffix.sd.mk.
-
-The top-level Dir.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 Dir.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
-------------------
-
-If want to set global variables, such as CC, that should only be done
-once. You can put them in your top-level Dir.sd.mk, or a separate
-file you `include' and declare using SUBDIRMK_MAKEFILES.
-
-If you need different settings of variables like CC for different
-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'
---------------------------------------------------------------------
-
-There are two kinds of template files.
-
- Filename .sd.mk .mk.in
-
- Processed by &-substitution, autoconf only
- then autoconf
-
- Instantiated Usu. once per subdir Once only
-
- Need to be mentioned No, but Dir.sd.mk All not in subdirmk/
- in configure.ac? via SUBDIRMK_SUBDIRS via SUBDIRMK_MAKEFILES
-
- How to include `&:include foo.sd.mk' `include foo.mk'
- in all relevant .sd.mk in only one
- (but not needed for Dir.sd.mk
- Prefix, Suffix, Final)
-
-If you `include subdirmk/regen.mk', dependency management and
-automatic regeneration for all of this template substitution, and for
-config.status etc. is done for you.
-
Substitution syntax
-------------------
&= => 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... &
&${..$..} => ${eval ${call ..$$..}}
(matches { } pairs to find the end)
- content is $-doubled (unless it contains $- to turn that off)
+ content is $-doubled (unless it contains &$- to turn that off)
- Together &:macro and &${...} provide a more reasonable macro
- facility than raw make. They solve the problem that make
- expansions cannot directly generate multiple rules, variable,
- etc.; instead, `$(eval )' must be used, but that re-expands
- the argument, meaning that all the literal text must be
- $-doubled. This applies to the macro text and to the
- arguments. Also `$(eval $(call ...))' is an unfortunate syntax.
- Hence &:macro and &${...}.
+Together &:macro and &${...} provide a more reasonable macro facility
+than raw make. They solve the problem that make expansions cannot
+directly generate multiple rules, variable, etc.; instead, `$(eval )'
+must be used, but that re-expands the argument, meaning that all the
+literal text must be $-doubled. This applies to the macro text and to
+the arguments. Also `$(eval $(call ...))' is an unfortunate syntax.
+Hence &:macro and &${...}.
While dollar-doubling:
- - - - - - - - - - -
get $-quadrupling.)
-Tables of file reference syntaxes
----------------------------------
+Invocation, "recursive" per-directory targets
+---------------------------------------------
-In a nonrecursive makefile supporting out of tree builds there are
-three separate important distinctions between different file
-locations:
+Arrangements are made so that when you run `make foo' in a
+subdirectory, it is like running the whole toplevel makefile, from the
+toplevel, as `make subdir/foo'. If `subdir/foo' is a file that might
+be built, that builds it.
- (i) In the build tree, or in the source tree ?
+But `foo' can also be a conventional target like `all'.
- (ii) In (or relative to) the subdirectory to which this Dir.sd.mk
- relates, or relative to the project's top level ?
+Each subdirectory has its own `all' target. For example a
+subdirectory `src' has a target `src/all'. The rules for these are
+automatically generated from the settings of the per-directory
+&TARGETS variables. &TARGETS is magic in this way. (In
+src/Dir.sd.mk, &TARGETS of course refers to a make variable called
+src_TARGETS.)
- (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).
+The `all' target in a parent directory is taken to imply the `all'
+targets in all of its subdirectories, recursively. And in the
+autogenerated stub Makefiles, `all' is the default target. So if you
+just type `make' in the toplevel, you are asking for `&all'
+(<subdir>/all) for every directory in the project.
-Path construction &-expansions are built from the following:
+In a parallel build, the rules for all these various subdirectory
+targets may be in run in parallel: there is only one `make' invocation
+at a time. There is no sequencing between subdirectories, only been
+individual targets (as specified according to their dependencies).
- Relative paths in...
- build source
-
- This directory & &^
- Top level . &~
+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).
-In more detail, with all the various options laid out:
+Prefix.sd.mk, Suffix.sd.mk, Final.sd.mk, inclusion
+--------------------------------------------------
- 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...)
+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 Dir.sd.mk, and the &-substituted contents therefore
+appear once for each subdirectory.
-(This assumes you have appropriate make variables src, PWD and
-abs_src.)
+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 Suffix.sd.mk.
+
+The top-level Dir.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 Dir.sd.mk.
+
+The file Final.sd.mk in the toplevel directory is processed and
+the result included after all the other files. Its subdirmk
+filtering context inherits warning suppressions from the toplevel's
+Dir.sd.mk etc., but not anything else.
+
+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)).
Warnings
--------
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.)
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).
+ 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
*dis*able an unknown warning is only reported if some other
warning was issued which might have been disabled.)
-Subdirectory and variable naming
---------------------------------
-The simple variable decoration scheme does not enforce a strict
-namespace distinction between parts of variable names which come from
-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
-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.
+Guides, hints, and further explanations
+=======================================
Incorporating this into your project
------------------------------------
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:
+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
&:include subdirmk/cdeps.sd.mk
&:include subdirmk/clean.sd.mk
+
Hints
-----
will clear up the problem.
+Global definitions
+------------------
+
+If want to set global variables, such as CC, that should only be done
+once. You can put them in your top-level Dir.sd.mk, or a separate
+file you `include' and declare using SUBDIRMK_MAKEFILES.
+
+If you need different settings of variables like CC for different
+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'
+--------------------------------------------------------------------
+
+There are two kinds of template files.
+
+ Filename .sd.mk .mk.in
+
+ Processed by &-substitution, autoconf only
+ then autoconf
+
+ Instantiated Usu. once per subdir Once only
+
+ Need to be mentioned No, but Dir.sd.mk All not in subdirmk/
+ in configure.ac? via SUBDIRMK_SUBDIRS via SUBDIRMK_MAKEFILES
+
+ How to include `&:include foo.sd.mk' `include foo.mk'
+ in all relevant .sd.mk in only one
+ (but not needed for Dir.sd.mk
+ Prefix, Suffix, Final)
+
+If you `include subdirmk/regen.mk', dependency management and
+automatic regeneration for all of this template substitution, and for
+config.status etc. is done for you.
+
+
+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 Dir.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 are built from the following:
+
+ Relative paths in...
+ build source
+
+ This directory & &^
+ Top level . &~
+
+In more detail, with all the various options laid out:
+
+ 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...)
+
+(This assumes you have appropriate make variables src, PWD and
+abs_src.)
+
+
+Subdirectory and variable naming
+--------------------------------
+
+The simple variable decoration scheme does not enforce a strict
+namespace distinction between parts of variable names which come from
+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
+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.
+
+
Legal information
------------------
+=================
subdirmk is
Copyright 2019 Mark Wooding