X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?p=subdirmk.git;a=blobdiff_plain;f=README;h=f79a280c5746f16954513f7023b5221deb2c0aef;hp=238607b6652412985ceb856aa8931547dcdb5962;hb=2a5416707829f758cd5435e1d7c6075e633ef3fd;hpb=f7fa99f4c599d405287c1af0111996c0a9d583eb diff --git a/README b/README index 238607b..f79a280 100644 --- a/README +++ b/README @@ -88,13 +88,13 @@ empty string). &= => 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 @@ -114,7 +114,7 @@ So pathname syntax is a subset of: &\$ => $ 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... & @@ -130,6 +130,10 @@ So pathname syntax is a subset of: &: .... recognised at start of line only (possibly after lwsp) +&: => &: + for make multiple targets syntax + recognised anywhere *except* start of line + &:include filename filename should usually be [&]foo.sd.mk &:-include filename tolerate nonexistent file RHS is &-expanded but filenames are relative to the top @@ -166,6 +170,9 @@ So pathname syntax is a subset of: `all' is extra special: every directory has an `all' target, which corresponds to &TARGETS. +Directives +- - - - - + &:warn [!]WARNTAG ... Suppress (with !) or re-enable (without !) warnings tagged WARNTAG (see section `Warnings', below). The suppression list @@ -174,10 +181,11 @@ So pathname syntax is a subset of: 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 @@ -205,6 +213,10 @@ Dollar doubling and macro assistance &$- 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. @@ -214,17 +226,18 @@ STUFF $ THINGS .. STUFF $$ THINGS &: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) + contrast &(...), see "Convenience syntax for call", below. -Together &:macro and &${...} provide a more reasonable macro facility +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 )' +directly generate multiple rules, variables, 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 &${...}. +Hence &:macro and &{...}. While dollar-doubling: - - - - - - - - - - - @@ -233,13 +246,29 @@ $ => $$ including $'s produced by other &-expansions not mentioned here &\$ => $ -&$NN => $(NN) where N are digits &$( => $( +&$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 call +- - - - - - - - - - - - - - + +&(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. + +Use this when the expansion is going to be a piece of text to be used +as part of a rule, filename, etc. When the expansion is top-level +make text (eg, rules), use &:macro and &{...}. + Invocation, "recursive" per-directory targets --------------------------------------------- @@ -311,6 +340,109 @@ subdirmk's filter script itself sets (only) these variables: 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 ------------------ @@ -322,6 +454,7 @@ 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' -------------------------------------------------------------------- @@ -388,36 +521,6 @@ In more detail, with all the various options laid out: (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 -------------------------------- @@ -434,73 +537,13 @@ 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 ------------------------------------- - -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-2020 Ian Jackson Copyright 2019 Mark Wooding - Copyright 2019 Ian Jackson subdirmk and its example is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public