X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=README;h=91b62d481de802a297f86cf7de5c3613ee215762;hb=refs%2Fheads%2Fwip.v2b;hp=0ab3b50057b5ed23172f7fa60b911fd8c9d47e23;hpb=172580f2d7fb712f40e036c1417718b443e4adb9;p=subdirmk.git diff --git a/README b/README index 0ab3b50..91b62d4 100644 --- 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'. -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 @@ -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. +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 ------------------ @@ -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. +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 ------------------- -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, @@ -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 -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 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 -\& => & 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. - 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. @@ -190,16 +266,29 @@ empty string). &:-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. + &! 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. @@ -207,12 +296,13 @@ empty string). 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) @@ -225,14 +315,40 @@ empty string). 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 -------------------------------- @@ -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. -`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 ------------------------------------ @@ -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 -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 -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