chiark / gitweb /
Syntax: only some directives' RHS should be &-expanded
[subdirmk.git] / README
diff --git a/README b/README
index 7fdeef52438817155503ce55cf72122e9e2b2050..63e41881b9674d440978d4f1076190f2df7fef3d 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,32 +153,46 @@ 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.
 
-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
 -------------------
 
 Substitution syntax
 -------------------
@@ -189,42 +218,45 @@ empty string).
        The assumption is that filenames are usually lowercase and
        variables usually uppercase.  Otherwise, use another 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 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:
 
 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 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:
 
 So pathname syntax is a subset of:
-    '&' [ '@' ] [ ',' | ';' | '.' ] [ lc | '/' ]
-
-    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 `&@/'.
+    '&' [ '^' | '~' ] [ lc | '/' | '.' | '=' ]
 
 &&             =>      &&              for convenience in shell runes
 
 &&             =>      &&              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
+&\$            =>      $
+
+&$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.
        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.
@@ -236,30 +268,31 @@ So pathname syntax is a subset of:
        recognised at start of line only (possibly after lwsp)
        args are processed for &
 
        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)
 &:-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)
 
 
 &!<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
        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:changequote &  set escape back to &
 
 &TARGETS_things
        Handled specially.  If mentioned, declares that this
 
 &TARGETS_things
        Handled specially.  If mentioned, declares that this
@@ -350,6 +383,13 @@ 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.
 
 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
 -----------------
 
 Legal information
 -----------------