* 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.
myproject
mylibrary
"""
-$ nailing-cargo generate-lockfile
+$ nailing-cargo -u fetch
$ nailing-cargo build
```
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] for full details.
+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.
+
+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.
+
+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
==================
`.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
------------------------------
`--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.
nailing-cargo configuration. `misc.online=false`, and command line
options, are also available, for overriding.
+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
============================================
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], below.)
+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
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 `-`.
+ 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
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'`.
+ equivalent to:
- * <a name="s_subcommand">`-s<subcommand>`</a>
+```
+[arch]
+RPI="arm-unknown-linux-gnueabihf"
+WASM="wasm32-unknown-unknown"
+```
- 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`.
+ * `-o` | `--online` | `-O` | `--offline`
- nailing-cargo knows about `update`, `generate-lockfile` and
- `fetch`; all other subcommands are (silently) treated the same way
- as `build` (ie, no subcommand properties). See
- [`--subcommand-props`](#subcommand_props) for more detail about how the
- subcommand affects nailing-cargo's behaviour.
+ 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.
- 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.
+ * `-u` | `--cargo-lock-update` | `-U` | `--no-cargo-lock-update`
+
+ 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`
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 - 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.
- * `-o` | `--online` | `-O` | `--offline`
-
- 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.
-
- * `-u` | `--cargo-lock-update` | `-U` | `--no-cargo-lock-update`
+ * <a name="s_subcommand">`-s<subcommand>`</a>
- Enables, or disables, the dance to allow `Cargo.lock` (or
- alternative) to be updated in the source directory.
+ 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`.
- 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.
+ nailing-cargo knows about the following commands:
+ * `fetch`
+ * `fmt`
+ * `generate-lockfile`
+ * `update`
- This makes no sense with in-tree builds.
+ 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.
- Default is no update unless the cargo subcommand will want it.
+ 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>
* `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. Produces warning if `--edit-sources` mode not specified.
* `!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
* `!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.
+
+ 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 is the default mode for `nailing-cargo fmt`.
+
+ * `--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
--------------------------------
* `command`: The command to run for `command_sh` or `command_args`.
- * `user`: The local username for `really` and `ssh`, or
- `<user>@<host>` for `ssh`.
+ 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
------------------------------------------
`[misc]`: Miscellaneous individual nailing-cargo config
-------------------------------------------------------
- * <a name="misc_online">`online`</a>: boolean, specifying whether to pass `--offline` to cargo
- (cargo's default is online mode). The default is offline, unless
- nailing-cargo can see that the cargo subcommand being invoked is
- one which requires online access (currently, `fetch`), in which
- case the default is online.
+ * <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
====================
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_propss` in the source, or use
+ add an entry to `@subcmd_props` in the source, or use
[`--subcommand-props`](#subcommand_props).
- * Out of tree builds require a unified filesystem view: eg, different
+ 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