chiark / gitweb /
nailing-cargo: Properly handle renamed packages
[nailing-cargo.git] / README.md
index 1550719719b68ff927c7e6c02ca08a5df522531f..78acb9e831384e14665abc74d6f5afcbdccb11b1 100644 (file)
--- a/README.md
+++ b/README.md
@@ -6,13 +6,10 @@ manager.  Functions:
 
  * Conveniently use local crates, including completely
    unpublished crates.
 
  * 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.
  * Perform out-of-tree builds, including in an account with
    no write access to the source tree.
-
  * Provide convenience aliases for target architecture names.
  * 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.
 
 
 These functions are of course configurable.
 
@@ -45,10 +42,41 @@ subdirs="""
 myproject
 mylibrary
 """
 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
 ==============================================
 
 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`
 -------------------------------------------------
 
 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
 ==================
 
 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`.
 
 `.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
 ------------------------------
 
 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`.
 
 `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
 =======================================
 
 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
 `--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.
 
 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.
 
 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.
 
 
   * `-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.
 
   * `-n`: "No action": stop after writing `Cargo.toml.nailing~`
        everywhere, and do not run any build command.
 
-  * `-A<arch>` | `--arch=<arch>` | `--target=<arch>`
+  * `-f` | `--force`: Force going ahead even if problems are likely.
+    (E.g., due to missing `-E` option.)
 
 
-       Specify target architecture.
+  * `-T<arch>` | `--target=<arch>`
 
 
-       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.
+    Specify target architecture.
 
 
-       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'`.
+    This option translates to a `--target=<arch>` option to cargo
+    (when the subcommand accepts it).
 
 
-  * `-u` | `--cargo-lock-update` | `-U` | `--no-cargo-lock-update`
-
-       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:
 ```
 
 nailing-cargo reads these configuration files:
 ```
@@ -257,8 +542,45 @@ nailing-cargo reads these configuration files:
 Settings in later-mentioned files override ones in earlier-mentioned
 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`.
 
 `[alt_cargolock]`: Alternative `Cargo.lock` filename
 ----------------------------------------------------
 
 `[alt_cargolock]`: Alternative `Cargo.lock` filename
 ----------------------------------------------------
@@ -278,22 +600,92 @@ To control use of alternative `Cargo.lock` filename, use the section
 
   * `force = true`: Always uses the alternative filename.
 
 
   * `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
 ====================
 
 Limitations and bugs
 ====================
@@ -307,7 +699,19 @@ Limitations and bugs
     At least, running nailing-cargo again will clean up any mess
     left by an interrupted run.
 
     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
+  * 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
     users on the same host, NFS, or something.
 
     Specifically, the invocation and build execution environments must