chiark / gitweb /
README: v2: Draft - Use / for variable names too. Use &. for just the name
[subdirmk.git] / README
diff --git a/README b/README
index 0ab3b50057b5ed23172f7fa60b911fd8c9d47e23..91b62d481de802a297f86cf7de5c3613ee215762 100644 (file)
--- a/README
+++ b/README
@@ -28,15 +28,17 @@ Basic approach
 The developer is expected to write a makefile fragment, in each
 relevant subdirectory, called `Subdir.sd.mk'.
 
 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
 
 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
 
 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
 
 The Subdir.sd.mk's are filtered, fed through autoconf in the usual way
 (for @..@-substitutions) and included by one autogenerated toplevel
@@ -103,6 +105,19 @@ is already provided in subdirmk, for you to reference like this:
   &:include subdirmk/clean.sd.mk
 For example you could put that in Perdir.sd.mk.
 
   &: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
 ------------------
 
 Global definitions
 ------------------
 
@@ -138,12 +153,52 @@ 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.
 
 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 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 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.)
+
 Substitution syntax
 -------------------
 
 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,
 
 Note that & is processed *even in makefile comments*.  The substitutor
 does not understand make syntax, or shell syntax, at all.  However,
@@ -153,32 +208,53 @@ are common in makefiles.
 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
 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:
+&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 TOP_
 &/             =>      sub/dir/                        or nothing
 &/             =>      sub/dir/                        or nothing
-&=_            =>      sub_dir                         or TOP
-&=/            =>      sub/dir                         or .
-&^             =>      $(top_srcdir)/sub/dir           or $(top_srcdir)
-&~             =>      $(abs_top_srcdir)/sub/dir       or $(abs_top_srcdir)
+&.             =>      sub/dir                         or .
+       (This implies that `&./' works much like `&/'. &./ is
+       suitable for variable name construction in a way &/ is not.)
+
+&^alpha                =>      $(top_srcdir)/sub/dir/alpha
+&^/            =>      $(top_srcdir)/sub/dir/
+&^.            =>      $(top_srcdir)/sub/dir
+
+&~alpha                =>      $(top_srcdir)/alpha
+&~/            =>      $(top_srcdir)/
+&~.            =>      $(top_srcdir)
+
+In general:
+    ^   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)
+
+&_             =>      ERROR (for compat with v1)
+
+So pathname and variable syntax is a subset of:
+    '&' [ '^' | '~' ] [ alpha... | '/' | '.' ]
 
 &&             =>      &&              for convenience in shell runes
 
 &&             =>      &&              for convenience in shell runes
-\&             =>      &               general escaping mechanism
+&@             =>      &               general escaping mechanism
+&&@            =>      &&               @ after any number of & vanishes
 
 
-& thing thing... &
-& ^ thing thing... &
-& ~ thing thing... &
+&$VARIABLE     $(sub/dir/VARIABLE)
+       VARIABLE is ASCII starting with a letter and matching \w+
+
+&  thing thing... &
+&/ thing thing... &
+&^ thing thing... &
+&~ thing thing... &
        Convenience syntax for prefixing multiple filenames.
        Convenience syntax for prefixing multiple filenames.
-       Introduced by & followed by lwsp (space or tab).
-       Each lwsp-separated non-ws word is prefixed by &/ &^/ &~/
-       respectively.  No other & escapes are recognised.
+       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.
 
        This processing continues until & preceded by lwsp,
        or until EOL (the end of the line), or \ then EOL.
 
@@ -190,16 +266,29 @@ empty string).
 &:-include filename            tolerate nonexistent file
        filenames are relative to $(top_srcdir)
 
 &:-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)
 
 &!<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,
        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.
 
        After this, write STUFF instead of &, everywhere.
        The effect is global and lasts until the next setting.
@@ -207,12 +296,13 @@ empty string).
        it back before using &:include.
 
        Notably
        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
 
 &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)
 
        subdir ought to have a target `things'.  The rule will be
                &/things:: $(&TARGETS_things)
 
@@ -225,14 +315,40 @@ empty string).
        arranges that the *parent* will also have a `things' target
        which recursively implies this directory's `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.
 
 
        `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 and variable naming
 --------------------------------
 
@@ -241,13 +357,10 @@ 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.
 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.
 
 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
 ------------------------------------
 
 Incorporating this into your project
 ------------------------------------
 
@@ -282,15 +395,18 @@ You can convert your project incrementally.  Start with the top-level
 Makefile.in and rename it to Subdir.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
 Makefile.in and rename it to Subdir.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.
+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.)
 
 Aside from this, be very wary of any invocation of $(MAKE) anywhere.
 This is a frequent source of concurrency bugs in recursive make build
 
 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 there is no
-separate-directory barrier stopping the different invocations ending
-up trying to make the same targets at the same time, which causes
-hideous racy lossage.  There are ways to get this to work reliably but
-it is advanced stuff.
+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
 
 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