chiark / gitweb /
nailing-cargo: Properly handle renamed packages
[nailing-cargo.git] / README.md
index a80739cfe19dbcee2a12328dd5586828f4328894..78acb9e831384e14665abc74d6f5afcbdccb11b1 100644 (file)
--- a/README.md
+++ b/README.md
@@ -6,13 +6,10 @@ manager.  Functions:
 
  * Conveniently use local crates, including completely
    unpublished crates.
-
  * Perform out-of-tree builds, including in an account with
    no write access to the source tree.
-
  * Provide convenience aliases for target architecture names.
-
- * Make the default be offline (ie, not to access the internet)
+ * Make the default be offline (ie, not to access the internet).
 
 These functions are of course configurable.
 
@@ -45,10 +42,41 @@ subdirs="""
 myproject
 mylibrary
 """
-$ nailing-cargo cargo generate-lockfile
-$ nailing-cargo cargo build
+$ nailing-cargo -u fetch
+$ nailing-cargo build
 ```
 
+Documentation table of contents
+-------------------------------
+
+<!-- TOC autogenerated by ./markdown-toc-filter, do not edit -->
+
+  * [Introduction](#nailing-cargo)
+    * [Installing](#installing)
+    * [Most basic example usage](#most-basic-example-usage)
+    * [Documentation table of contents](#documentation-table-of-contents)
+  * [Using local crates, or locally modified crates](#using-local-crates-or-locally-modified-crates)
+    * [How nailing-cargo helps with using local crates](#how-nailing-cargo-helps-with-using-local-crates)
+    * [Telling nailing-cargo how to massage `Cargo.toml`](#telling-nailing-cargo-how-to-massage-cargo.toml)
+  * [Out-of-tree builds](#out-of-tree-builds)
+    * [How nailing-cargo helps with out-of-tree builds](#how-nailing-cargo-helps-with-out-of-tree-builds)
+    * [Configuring out-of-tree builds](#configuring-out-of-tree-builds)
+  * [Target architecture convenience aliases](#target-architecture-convenience-aliases)
+  * [Default change to offline mode](#default-change-to-offline-mode)
+  * [Invocation and command-line option reference](#invocation-and-command-line-option-reference)
+    * [Usages](#usages)
+    * [Options](#options)
+    * [Environment of the build command](#environment-of-the-build-command)
+  * [Configuration reference](#configuration-reference)
+    * [Source directories and packages (toplevel)](#source-directories-and-packages-toplevel)
+    * [`[alt_cargolock]`: Alternative `Cargo.lock` filename](#alt_cargolock-alternative-cargo.lock-filename)
+    * [`[oot]`: Out-of-tree build support](#oot-out-of-tree-build-support)
+    * [`[arch]`: Architecture convenience aliases](#arch-architecture-convenience-aliases)
+    * [`[misc]`: Miscellaneous individual nailing-cargo config](#misc-miscellaneous-individual-nailing-cargo-config)
+  * [Limitations and bugs](#limitations-and-bugs)
+  * [Contributing and legal](#contributing-and-legal)
+    * [Legal](#legal)
+
 Using local crates, or locally modified crates
 ==============================================
 
@@ -73,22 +101,36 @@ cargo; and then it puts everything back.
 Telling nailing-cargo how to massage `Cargo.toml`
 -------------------------------------------------
 
-To find the subdirectories, and the packages, it looks for `subdirs`
-and `packages` in `Cargo.nail`.
+To find the subdirectories, and the packages, nailing-cargo looks for
+`subdirs` and `packages` in `Cargo.nail`.
+
+For straightforward use, write `subdirs` as a multi-line string
+containing a list of subdirectory names one per line.  In each of
+these directories `Cargo.toml` will be massaged, and the package there
+will be used for other massaged `Cargo.toml`s.
+
+See the [Configuration reference](#configuration-reference) for full details.
+
+Scope of nailing-cargo's local crate functionality
+--------------------------------------------------
+
+nailing-cargo's `Cargo.toml` massaging will allow you to easily build
+an interdepending set of local packages, possibly even including
+private unpublished packages, and/or locally-modified versions of
+published packages.  These local packages can freely depend on
+published packages (eg from `crates.io`) in the usual way.
 
-`subdirs` can be a (usually multi-line) string containing a list of
-subdirectory names one per line.  (`#`-comments are supported.)  Or it
-can be a list of strings (`subdirs = ['myproject','mylibrary']`).  In
-each of these directories `Cargo.toml` will be massaged, and
-the package there will be used for other massaged `Cargo.toml`s
+Compared to the corresponding cargo feature, nailing-cargo's approach:
+(i) works even for local crates that have not been published anywhere; and
+(ii) is a lot simpler to configure.
 
-For more complex cases: `packages` is a mapping from package names to
-strings or dictionaries (e.g. in `Cargo.nail`, write something like:
-`[packages.mylibrary]` `subdir='mylibrary-test'` or `[packages]`
-`mylibrary='mylibrary-test'`).  These override the locations for the
-specified packages (so you can, for example, have multiple trees with
-the same package in).  These subdirectories are also added to the list
-of places where `Cargo.toml` should be massaged.
+But nailing-cargo's local crate support won't work if any non-local
+crate needs to be rebuilt against a local crate (ie, a local version
+of one of its dependencies).  If that is your requirement, either make
+local versions of the intermediate crates in the dependency graph, or
+use the cargo override facility --- see [Overriding
+Dependencies](https://doc.rust-lang.org/cargo/reference/overriding-dependencies.html)
+in the Cargo Book.
 
 Out-of-tree builds
 ==================
@@ -115,6 +157,12 @@ nailing-cargo arranges this for you.  You can either put this file in
 `.gitignore`; or commit it to git; or you can tell nailing-cargo to
 save it as something like `Cargo.lock.example`.
 
+Depending on the circumstances, nailing-cargo uses a variety of
+strategies, including `--manifest-path` options, and linkfarming, to
+make out of tree builds.  Some crates don't natively support
+out-of-tree builds, in which case passing a `--linkfarm` option to
+nailing-cargo can be helpful.
+
 Configuring out-of-tree builds
 ------------------------------
 
@@ -122,29 +170,17 @@ To enable out-of-tree-builds, put an `[oot]` section in your
 `Cargo.nail` or one of nailing-cargo's other config files.
 In that section, specify at least `use`.
 
-The primary config keys here are:
+Also, specify `dir`, or create a symlink `Build` next to `Cargo.nail`,
+pointing to to your build area.
 
-  * `dir`: The build directory.  If relative, it is relative to the
-   parent of the invocation directory (and could be a symlink then).
-   Default is `Build` (assuming `use` is specified).
-
-  * `use`: How to become the build user.  Needs to be combined
-    with other setting(s):
-
-    * `ssh`: Use ssh.  `user` must be given as well and can be
-       a username on localhost, or the `<user>@<host>`
-       argument to ssh.
-
-    * `command_args`: `command` must be specified as a list,
-       specifying a command and arguments which work like `nice`.
-
-    * `command_sh`: `command` must be specified as a list,
-       specifying a command and arguments which work like `sh -c`.
-
-    * `null`: Run builds as the same user.
-
-    * `really`: Use `really` from `chiark-really.deb`.
-       `user` must be given as well.
+For example,
+```
+[oot]
+use='ssh'
+user='rustcargo'
+```
+will have nailing-cargo run `ssh rustcargo@localhost` to
+run build commands.
 
 Target architecture convenience aliases
 =======================================
@@ -156,7 +192,7 @@ A simple shell alias would help a lot, except that cargo rejects
 `--target=` when it thinks it's not needed.
 
 In your nailing-cargo config, you can write something like
-`arch.RPI='arm-unknown-linux-gnueabihf'`.  Then `nailing-cargo -ARPI`
+`arch.RPI='arm-unknown-linux-gnueabihf'`.  Then `nailing-cargo -TRPI`
 will DTRT.  In fact, you do not even need to specify that particular
 arch alias, since it is built-in to nailing-cargo.
 
@@ -171,8 +207,69 @@ If you disagree with my opinion, write `misc.online=true` in your
 nailing-cargo configuration.  `misc.online=false`, and command line
 options, are also available, for overriding.
 
-Command-line options
-====================
+If you agree with me, you may wish to use `nailing-cargo
+generate-lockfile`, which can update (even an existing) `Cargo.lock`
+without going online, instead of `update`.
+
+Invocation and command-line option reference
+============================================
+
+Usages
+------
+
+```
+1$ nailing-cargo <nailing-opts> <cargo-opts> [--] <subcmd>...
+2$ nailing-cargo <nailing-opts> --- <cargo> <cargo-opts> [--] <subcmd>...
+3$ nailing-cargo <nailing-opts> --- [--] <build-command>...
+```
+Ususally the `--` is not needed.  (It should generally be passed by
+programs which wrap nailing-cargo.  See [Invocation argument disambiguation rules](#invocation-argument-disambiguation-rules), below.)
+
+In usage 1, nailing-cargo runs `cargo` (from `PATH`).  In the usage 2
+nailing-cargo runs `<cargo>`.  In both these cases it adds its own
+options to control cargo's behaviour.  In both of these cases
+nailing-cargo looks at `<subcmd>` to determine the cargo subcommand
+being run: this controls various defaults, to try to do the right
+things.
+
+In the third syntax, nailing-cargo runs `<build-command>...` without
+additional arguments and does not attempt to identify the cargo
+subcommand(s) that it will run.  Possibly it will be necessary to pass
+`--online` or `--cargo-lock-update`, or even `--cargo-*arg*`
+
+### Invocation argument disambiguation rules ###
+
+For authors of tools which call nailing-cargo (and pedants):
+
+The usages overlap in syntax!  nailing-cargo follows the following
+rules when interpreting its command line:
+
+  * The first option not recognised as a nailing-cargo option is
+    treated as the start of the `<cargo-opts>`.
+
+  * `<cargo-opts>` are terminated by `--` (which is removed) or the
+    first argument which does not start with a `-` or `+`.
+
+    (It is not possible to get nailing-cargo to pass the value `--`
+    as a separate argument to a cargo global option, but cargo global
+    options can typically take the values cuddled with `=`, so doing
+    that is not necessary.)
+
+  * After `---`, nailing-cargo will search for a `--`, to the end of
+    the arguments if necessary.  The position of the `--` determines
+    whether this is usage 2 or usage 3, and what `<subcmd>` is.
+
+    If the arguments after `nailing-cargo ... ---` might contain `--`
+    anywhere, an explicit `--` should be passed.
+
+  * If no `--` appears after `---`, the word after `---` is the
+    command to run; if its final pathname component contains the
+    string `cargo`, it is treated as `<cargo>` (implying usage 2 and
+    the search for `<subcmd>`).  Otherwise it is treated as
+    `<build-command>` (usage 3).
+
+Options
+-------
 
   * `-v`: Increase verbosity.  Default is 1.
 
@@ -183,68 +280,256 @@ Command-line options
   * `-n`: "No action": stop after writing `Cargo.toml.nailing~`
        everywhere, and do not run any build command.
 
-  * `-A<arch>` | `--arch=<arch>` | `--target=<arch>`
-
-       Specify target architecture.
+  * `-f` | `--force`: Force going ahead even if problems are likely.
+    (E.g., due to missing `-E` option.)
 
-       This option translates to a `--target=<arch>` option to the
-       ultimate command, unless that is a cargo subcommand which we
-       know would reject it.  `--arch` and `--target` are simply
-       aliases.
+  * `-T<arch>` | `--target=<arch>`
 
-       If `<arch>` starts with a capital ascii letter, it is an alias
-       for some other arch: it is looked up in the configuration, and
-       then in the builtin arch alias list.  The builtin list is
-       equivalent to: `[arch]` `RPI='arm-unknown-linux-gnueabihf'`.
+    Specify target architecture.
 
-  * `-u` | `--cargo-lock-update` | `-U` | `--no-cargo-lock-update`
+    This option translates to a `--target=<arch>` option to cargo
+    (when the subcommand accepts it).
 
-       Enables, or disables, the dance to allow `Cargo.lock` (or
-       alternative) to be updated in the source directory.
+    If `<arch>` starts with a capital ascii letter, it is an alias
+    for some other arch: it is looked up in the configuration, and
+    then in the builtin arch alias list.  The builtin list is
+    equivalent to:
 
-       With this dance enabled the `Cargo.lock` and `Cargo.toml` are
-       copied to the build directory along with a skeleton just big
-       enough to fool cargo.  After cargo has run, the resulting
-       `Cargo.lock` is copied back to the source tree.
+```
+[arch]
+RPI="arm-unknown-linux-gnueabihf"
+WASM="wasm32-unknown-unknown"
+```
 
-       This makes no sense with in-tree builds.
+  * `-o` | `--online` | `-O` | `--offline`
 
-       Default is no update unless the ultimate command is a
-       cargo subcommand which we know needs it.
+    Whether to allow cargo to make network access.  nailing-cargo
+    always passes `--offline` to cargo, unless `--online` is in
+    force.  The default value depends on the configuration and the
+    cargo subcommand - see [`[misc]` `online`](#misc_online),
+    under Configuration.
 
-  * `-m` | `--cargo-manifest-args` | `-M` | `--no-cargo-manifest-args`
+  * `-u` | `--cargo-lock-update` | `-U` | `--no-cargo-lock-update`
 
-       Controls whether we add cargo command line options, relating to
-       finding `Cargo.toml`, to the command to run.
+    Allows (or disallows) cargo to update `Cargo.lock` in the source
+    directory.  Without this enabled, nailing-cargo passes `--locked`
+    to cargo.
+
+    With this enabled, in an out-of-tree build the `Cargo.lock` and
+    `Cargo.toml` are copied to the build directory along with a
+    linkfarm, to fool cargo.  After cargo has run, the resulting
+    `Cargo.lock` is copied back to the source tree.
+
+    Default is no update unless the whole point of the cargo
+    subcommand is to update `Cargo.lock`.
+
+  * `-c` | `-C`
+
+    Controls the addition of cargo command line options; ie,
+    whether nailing-cargo should treat the build command as if it
+    were cargo.
+    With `-C`, nailing-cargo will not add additional options
+    to the build command.  With `-c` it will pass those options
+    after the cargo subcommand (usages 1 and 2) or right
+    after the build command (usage 3).
+
+    The cargo options are in any case also passed in the
+    environment - see [Environment of the build command](#environment-of-the-build-command).
+
+    The default is to pass cargo options if the command line
+    parsing yielded a cargo command and options (usages 1 and 2),
+    rather than a non-cargo build command (usage 3).  `-C` and `-c`
+    do not affect the parsing of nailing-cargo's command line.
+
+  * <a name="s_subcommand">`-s<subcommand>`</a>
+
+    Behave as if the build command were `cargo <subcommand>`.
+    This influences the logic which tries to determine which
+    options to pass to cargo, whether cargo needs to be online, and
+    whether cargo might want to update `Cargo.lock`.
+
+    nailing-cargo knows about the following commands:
+     * `fetch`
+     * `fmt`
+     * `generate-lockfile`
+     * `update`
+
+    All other subcommands are (silently) treated the same way
+    as `build` (ie, no subcommand properties).  See
+    `--subcommand-props` for more detail about how the
+    subcommand affects nailing-cargo's behaviour.
+
+    The default is to use the cargo subcommand found from parsing
+    nailing-cargo's command line.  NB: `-s` does not affect
+    which build command (and which cargo subcommand) is actually run.
+
+  * <a name="subcommand_props">`--subcommand-props=<prop>,...`</a>
+
+    Specify the properties of the subcommand.  This is an
+    alternative to `-s<subcmd>`.  The usual properties are:
+
+    * `lock_update`: cargo will want to update `Cargo.lock`.  (The `-u` and `-U` options override this.)
+    * `online`: this subcommand makes no sense to run offline.  (The `-o` and `-O` options, and the configuration, can override this.)
+    * `edits`: The purpose of this subcommand is to edit the source tree.  Imples that `--edit-sources` is necessary (unless `--force`).
+    * `creates`: The purpose of this subcommand is to edit the source tree and create new files in it.  Imples that `-EE` (`--edit-sources`, twice) is necessary (unless `--force`).
+    * `!target`: cargo would reject `--target=<arch>`; in this case nailing-cargo's `-T` option is ineffective.
+    * `!target-dir`: cargo would reject `--target-dir`, so don't pass it.  (Usually we pass `--target-dir=target` when we pass `--manifest-path`, since cargo's default is `target` in the same directory as `Cargo.toml`.)
+    * `linkfarm-shallow`: Make the default be `--linkfarm=shallow`.  This is the default for `miri` and can also be used for other subcommands which do not understandg `--manifest-path` properly.
+    * `linkfarm-gitclean`: Make the defaults be `--linkfarm=git` and `--preclean-build=src`.
+
+    There are also some properties which should not be needed, but are
+    provided for completeness.  Do not use these to solve the problem
+    of nailing-cargo passing cargo options to a build command which is
+    not cargo - use `-C` for that.  The properties whose use is discouraged:
+
+    * `!manifest-path`: cargo would reject `--manifest-path`, so don't pass it (and don't pass `--target-dir` either).  Only makes any difference for out-of-tree builds.  Things will probably go wrong unless the build command looks at `[NAILING]CARGO_MANIFEST_DIR`.
+    * `!locked`: cargo would reject `--locked`, so don't pass it.  Hazardous.
+    * `!offline`: the build command would reject `--offline`, so never pass it.  *Not* overridden by configuration or command line.
+
+
+  * `--linkfarm[=no|shallow|git|full]`: Override nailing-cargo's
+    approach to out-of-tree builds.  Normally nailing-cargo chooses
+    automatically whether to make a linkfarm, and precisely what kind
+    of linkfarm, based on the cargo subcommand.  The linkfarm styles
+    are:
+
+    * `no`: Do not make a linkfarm; pass a `--manifest-path` option
+      pointing to the actual source directory.  This is the default
+      for most cargo commands.
+
+    * `shallow`: Symlink top-level objects in the source directory,
+      including whole subdirectories.  This the default when
+      nailing-cargo thinks cargo is going to update `Cargo.lock`.
+
+    * `git`: Make a deep linkfarm, with subdirectories.  Symlink
+      those objects tracked by git.  This is the default for
+      `cargo publish`.
+
+    * `full`: Make a deep linkfarm and symlink every nondirectory found
+      in the source tree.  This will including all sorts of junk,
+      including for example editor backup files.
+
+    Whenever nailing-cargo linkfarms, old symlinks pointing back to
+    the source tree are deleted.  In each case, `Cargo.lock` is not
+    symlinked, but copied.  If nailing-cargo expects cargo to update
+    `Cargo.lock`, it will copy it back to the source tree afterwards.
+    Just `--linkfarm` is the same as `--linkfarm=git`.
+
+  * `--edit | --edit-sources | -E`: Permits the cargo command to edit
+    sources in the source tree.  This is achieved by *copying* the
+    entire source tree (all files tracked by git) into the destination
+    directory, and then copying back all changed files.  *Only git
+    tracked filles* can be edited by the cargo command; edits to
+    other files, and creation of new files, will be ignored.
+
+    When this option is repeated (**`-EE`**), the cargo subcommand can
+    create new files including dotfiles (but nothing in the toplevel
+    `target` and nothing called `.git`).  (This also enables
+    `--preclean=src` by default.)
+
+    If you are running out of tree builds for privsep reasons, you
+    should use git to review the edits made by the cargo command and
+    either stage and commit them, or reject them.
+
+    This option is overridden by a subsequent `--linkfarm` options.
+
+    `-E` or `-f` is needed for `nailing-cargo fmt`.  `-EE` or `-f` is
+    needed for `nailing-cargo init`.  (`-E` is never the default.)
+
+  * `--just-linkfarm[=shallow|git|full]`: Make the out-of-tree
+    linkfarm as if for `--cargo-lock-update`, but do not actually run
+    any command, nor try to copy back a a generated `Cargo.lock`.
+    Forces `--keep-linkfarm` (even if the contrary is also specified).
+
+    With a linkfarming mode, overrides (and is overridden by)
+    `--linkfarm=`.  Without a linkfarming mode, and without
+    `--linkfarm`, the default is `shallow`.
+
+  * `--keep-linkfarm` | `--clean-linkfarm`: When doing an out-of-tree
+    lockfile update, controls whether the linkfarm is kept afterwards.
+    Overrides the `oot.clean` config option.  (Default: keep.)
+
+  * `--[no-]preclean-build[=no|src|full]`: When doing an out-of-tree
+    build, controls whether the build directory is purged of leftover
+    contents *before* the build is run.  The usual default is `no`.
+    For `cargo publish`, the default is `src`, which deletes
+    everything except the directory `target`.  `full` means to clean
+    out that too.
+
+  * `--leave-nailed`: At the end, leave all the `Cargo.toml` files in
+    their edited state, rather than (trying to) clean them up.  To
+    clean this up later, run `nailing-cargo` again without this option.
+    Without this option, the nailed versions are left in
+     `.Cargo.toml.nailed~`, so you only need this if you want to run
+    cargo by hand or something.
+
+  * `--just-run`: Execute the specified command (perhaps concurrently
+    with other commands), but do not manipulate any of Cargo's
+    metadata fiules.  Useful in out of tree mode to invoke a non-cargo
+    command in the build environment.  Implies `--no-nail`,
+    `--no-cargo-lock-manip` and `--no-concurrency-lock` (overrideable
+    by later occurrences of the corresponding opposite options).
+    Hazardous if the command is actually cargo, or will run cargo.
+
+  * `--no-nail` | `--nail` (default): Whether to actually nail - ie,
+    whether to actually modify any `Cargo.toml`s while running the
+    command.  This can be useful, e.g., in out-of-tree mode with
+    commands that don't actually invoke cargo.  Consider passingm
+    `--no-lock` too.
+
+  * `--no-cargo-lock-manip` | `--cargo-lock-manip` (default):
+    Whether to manipulate `Cargo.lock`.  For example, whether to copy
+    it to the build tree and back (in out of tree mode) and whether to
+    rename it from an alternative lockfile name, and put it back.
+    Overrides `-u` etc.
+
+  * `--no-concurrency-lock` | `--concurrency-lock` (default): Whether
+    to take the nailing-cargo lock.  Some kind of protection against
+    concurrent operation is necessary to prevent multiple instances of
+    nailing-cargo trashing each others' work, and possibly mangling
+    your `Cargo.toml`s, `Cargo.lock`, etc., so `--no-concurrency-lock`
+    is dangerous unless you take other measures against concurrent
+    execution.
+
+  * `-h` | `--help`: Print usage summary.
+
+  * `--doc` | `--man` | `--manual`: Format this manual into html using
+    `pandoc` and display it with `w3m`.
+
+Environment of the build command
+--------------------------------
 
-       Default is to add them if we are doing an out-of-tree build,
-       unless we are doing the dance to update the `Cargo.lock` (see
-       above) since in that case all the relevant files can be found
-       by cargo in the build directory.
+nailing-cargo passes these environment variables to the build command:
 
-       The arguments added are
+  * `CARGO_MANIFEST_DIR`: invocation `.` (invocation directory)
+  * `NAILINGCARGO_MANIFEST_DIR`: same as `CARGO_MANIFEST_DIR`
+  * `NAILINGCARGO_WORKSPHERE`: invocation `..` (parent)
+  * `NAILINGCARGO_BUILD_DIR`: build directory (even if same as source)
+  * `NAILINGCARGO_BUILDSPHERE`: parent of build dir (only set if out-of-tree)
+  * `NAILINGCARGO_CARGO_OPTIONS`: additional options that nailing-cargo passed (or would pass) to cargo.  Space-separated; does not include `--manifest-path`.
 
-           --manifest-path=<path/to/Cargo.toml>
-           --locked
-           --target-dir=target
+All of these are absolute paths.
 
-  * `-T` | `--no-cargo-target-dir-arg` | `-t` | `--cargo-target-dir-arg`
+### Build commands which wrap cargo ###
 
-       `-T` suppresses `--target-dir`; `-t` un-suppresses it.  Only
-       makes any difference with `-m`, since otherwise no
-       `--target-dir` would be passed anyway.  Additionally this is
-       done automatically when nailing-cargo sees that the cargo
-       subcommand is one which needs it, eg `fetch`.
+If you specify a build command which eventually runs cargo, you may
+wish to pass on to your cargo the options which nailing-cargo would
+have passed.  This will definitely be necessary if you are using nailing-cargo's out-of-tree facility.
 
-  * `-o` | `--online` | `-O` | `--offline`
+In such a situation, do it like this:
+```
+  cargo build --manifest-path="${CARGO_MANIFEST_DIR-.}"/Cargo.toml $NAILINGCARGO_CARGO_OPTIONS
+```
 
-       Whether to allow cargo to make network access.  nailing-cargo
-       always passes `--offline` to cargo, unless `--online` is in
-       force.  The default is offline, unless the cargo subcommand is
-       one which implies online (currently, `fetch`).
+If you need to run a cargo subcommand which doesn't understand some of
+nailing-cargo's options, currently, you must strip them out of
+`NAILINGCARGO_CARGO_OPTIONS` yourself - or pass some `-s` or
+`--subcmd-props` option to nailing-cargo (but that is a layering
+violation and may not work if one build command runs various different
+cargo runes).
 
-Configuration
-=============
+Configuration reference
+=======================
 
 nailing-cargo reads these configuration files:
 ```
@@ -257,11 +542,48 @@ nailing-cargo reads these configuration files:
 Settings in later-mentioned files override ones in earlier-mentioned
 files.
 
-Note that unlike everything else, `packages` and `subdirs` are read
-only from `Cargo.nail` (see "Limitations and bugs", below).
+Source directories and packages (toplevel)
+------------------------------------------
+
+Note that unlike everything else, these keys (`packages` and
+`subdirs`) are read only from `Cargo.nail` (see "Limitations and
+bugs", below).
+
+These keys specify a combination of (i) a mapping from package name to
+source subdirectory (ii) a set of subdirectories whose `Cargo.toml`
+must be massaged.
+
+  * `packages`: a map keyed by package name, giving the subdirectory
+    for each one.
+
+    This causes each mentioned subdirectory's `Cargo.toml` to be
+    massaged, and records that subdirectory as the source for that
+    package.  (nailing-cargo will check that subdirectory actually
+    contains the indicated package.)
+
+    Each value can be just the subdirectory name (eg `[packages]`
+    `mylibrary='mylibrary-test'`) or itself a map with the key `subdir`
+    (eg `[packages.mylibrary]` `subdir='mylibrary-test'`).
+
+  * `subdirs`: a list of subdirectory names to process.
+
+    Each subdirectory's `Cargo.toml` will be massaged.  Also, the
+    subdirectory will be examined to see what package it contains; it
+    will then be used as the source for that package, unless that
+    package appears in an entry in `packages`, or an earlier entry in
+    `subdirs`.
+
+    This can be a list of strings (eg `subdirs =
+    ['myproject','mylibrary']`).  Or it can be single multi-line
+    string containing one subdirectory name per line; in that
+    case, `#`-comments are supported and tabs and spaces are ignored
+    (see "Most basic example usage" above.)
+
+In each case the subdirectory should usually be a relative pathname;
+it is relative to the directory containing `Cargo.nail`.
 
-Alternative `Cargo.lock` filename
----------------------------------
+`[alt_cargolock]`: Alternative `Cargo.lock` filename
+----------------------------------------------------
 
 To control use of alternative `Cargo.lock` filename, use the section
 `[alt_cargolock]`.  Settings here:
@@ -278,22 +600,92 @@ To control use of alternative `Cargo.lock` filename, use the section
 
   * `force = true`: Always uses the alternative filename.
 
-Running the command
-===================
+`[oot]`: Out-of-tree build support
+----------------------------------
 
-Normally you pass cargo as an argument to nailing-cargo.  But you
-can also pass make or any other command.  You may need to pass
-`--no-cargo-manifest-args` (aka `-M`) to nailing-cargo, to avoid
-passing options like `--manifest-path` to make or whatever.
+  * `dir`: The build directory.  If relative, it is relative to the
+   parent of the invocation directory (and could be a symlink then).
+   Default is `Build` (assuming `use` is specified).
 
-nailing-cargo passes these environment variables to the build command:
+   The build directory will contain one subdir for each package: each
+   subdir in the build dir corresponds to one source dir where
+   nailing-cargo was invoked.  nailing-cargo will arrange to create
+   these subdirectories, so the build directory can start out empty.
 
-  * `NAILINGCARGO_WORKSPHERE`: invocation `..` (parent)
-  * `NAILINGCARGO_MANIFEST_DIR`: invocation `.` (invocation directory)
-  * `NAILINGCARGO_BUILD_DIR`: build directory (even if same as source)
-  * `NAILINGCARGO_BUILDSPHERE`: only set if out of tree: parent of build dir.
+  * `use`: How to become the build user.  Needs to be combined
+    with other setting(s):
 
-All of these are absolute paths.
+    * `ssh`: Use ssh.  `user` must be given as well and can be
+       a username on localhost, or the `<user>@<host>`
+       argument to ssh.
+
+    * `command_args`: `command` must be specified as a list,
+       specifying a command and arguments which work like `nice`.
+
+    * `command_sh`: `command` must be specified as a list,
+       specifying a command and arguments which work like `sh -c`.
+
+    * `null`: Run builds as the same user.
+
+    * `really`: Use `really` from `chiark-really.deb`.
+       `user` must be given as well.
+
+    * `disable': Disable this feature, even if `dir` is set.
+
+ * `command`: The command to run for `command_sh` or `command_args`.
+
+   In both cases, this is a command and its arguments/options.  The
+   list will be passed to `execvp`.  The difference between
+   `command_args` and `command_sh` is in what nailing-cargo appends to
+   the specified `command` list:
+
+   For `command_args`, nailing cargo appends multiple more arguments;
+   each one should be passed as-is as a single argument to the actual
+   build command.  This is correct if `command` is a program like
+   `nice` or `really`, which takes a command and its arguments and
+   does not go via the shell.
+
+   For `command_sh`, nailing-cargo appends one single further
+   argument.  That argument is a shell command; nailing-cargo
+   constructs it by shell-quoting the real command and arguments and
+   wrapping them up in a small script, the text of which becomes the
+   extra argument to `command`.  This is correct if `command` will
+   pass its argument to a bournelike shell - for example, if `command`
+   is an ssh rune for a remote account whose shell is `/bin/sh` or
+   `/bin/bash`.
+
+ * `user`: The build username, for `really` and `ssh`.  For `ssh`, can
+   be just the local username (meaning `@localhost`), or
+   `<user>@<host>`.
+
+ * `clean` (boolean): When doing a `Cargo.lock` update, which involves
+   linkfarming in the build directory, whether the clean up the
+   linkfarm afterwards.  Default: `true`.  Can be overridden by
+   `--keep-linkfarm` or `--clean-linkfarm`.
+
+`[arch]`: Architecture convenience aliases
+------------------------------------------
+
+This is a map from archictecture aliases to full cargo architecture
+names.  The keys are the aliases; each entry should be a string, the
+cargo architecture name.
+
+Only keys starting with an ascii uppercase letter are relevant, since
+other names are not looked up in this alias map.
+
+`[misc]`: Miscellaneous individual nailing-cargo config
+-------------------------------------------------------
+
+ * <a name="misc_online">`online`</a>:
+
+   Specifies whether to allow or prevent cargo from accessing the
+   network.  Value is a boolean or `'auto'`.  `'auto'` permits online
+   access if the cargo subcommand being invoked is one whose main
+   purpose involves online access.
+
+   Implemented by passing `--offline` to cargo when necessary ---
+   cargo's default is online.  nailing-cargo's default is
+   `'auto'`.
 
 Limitations and bugs
 ====================
@@ -307,10 +699,30 @@ Limitations and bugs
     At least, running nailing-cargo again will clean up any mess
     left by an interrupted run.
 
-  * Out of tree builds require a unified filesystem view: eg, different
-    users on the same host, NFS, or something.  This could be improved.
+  * nailing-cargo needs to understand the behaviour of the cargo
+    subcommand you are running - especially for out-of-tree builds.
+    nailing-cargo only has a short builtin list of commands it knows
+    about (see [`-s<subcommand`](#s_subcommand)).  For other commands, you may need to
+    add an entry to `@subcmd_props` in the source, or use
+    [`--subcommand-props`](#subcommand_props).
+
+    Contributions of additonal entries to `@subcmd_props` (or bug
+    reports about missing entries) are of course very welcome.
+
+  * Out-of-tree builds ought to support `sudo`.  Patches welcome.
+
+  * Out-of-tree builds require a unified filesystem view: eg, different
+    users on the same host, NFS, or something.
+
+    Specifically, the invocation and build execution environments must
+    both have visibility of the source and build directories, at the
+    same absolute pathnames.  The invocation environment must be able
+    to write to the build environment (but vice versa is not
+    required).
+
+    This could be improved.
 
-    The alternative `Cargo.lock` filename must currently be a leafname.  I
+  * The alternative `Cargo.lock` filename must currently be a leafname.  I
     think fixing this just involves review to check other values work
     properly.