* `-c<subcommand>`
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`.
- But this option does not affect which build command (and which
+ nailing-cargo knows about `update`, `generate-lockfile` and
+ `fetch`; all other subcommands are (silently) treated the
+ same way as `build`. See `--subcommand-props`, below, for
+ more detail about how the subcommand affects nailing-cargo's
+ behaviour.
+
+ This option does not affect which build command (and which
cargo subcommand) is actually run.
+ The default is to look into the command line to find the cargo
+ subcommand.
* `-C`
But this option does not affect which build command is actually
run.
+ The default is to treat the build command as cargo unless a
+ build command is specified whose leafname does not contains the
+ string `cargo`.
+
+ * `-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` in "Configuration".
+
* `-u` | `--cargo-lock-update` | `-U` | `--no-cargo-lock-update`
Enables, or disables, the dance to allow `Cargo.lock` (or
Default is no update unless the cargo subcommand will want it.
- * `--cargo-args=<ena><opt>[,<ena><opt>...]`
-
- Overrides the logic for choosing which cargo options should be
- passed to the build command.
- The value is a comma-separated list of `<ena><opt>`.
-
- `<opt>` is one of the arguments that nailing-cargo might pass
- to cargo: `manifest-path`, `locked`, `target-dir`, `offline`,
- `arch`.
- (Note these must be specified
- without the leading `--` and without any value.) `<opt>` may
- also be `all` in which case the setting for all options is
- changed.
+ * `--subcommand-props=<prop>,...`
- The specs (maybe multiple `--cargo-args` options) are
- cumulative and are processed in order. These options override
- `-c`, `-C`. They can also effectively override other options
- to nailing-cargo, such as `--offline` or `--target`.
+ Specify the properties of the subcommand. This is an
+ alternative to `-c<subcmd>`. The properties are:
- `<ena>` is one of:
-
- * `@`: Decide automatically for this option (default).
- * `+`: Definitely pass this option
- * `-`: Definitely do not pass this option
- * `_`: Definitely do not pass this option - and do not mind if `<opt>` is not known to nailing-cargo.
-
- * `-T` | `--no-cargo-target-dir-arg` | `-t` | `--cargo-target-dir-arg`
-
- `-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`.
-
- * `-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` in "Configuration".
-
-Arguments to the build command
-------------------------------
-
-xxx
- * `-m` | `--cargo-manifest-args` | `-M` | `--no-cargo-manifest-args`
-
- Controls whether we add cargo command line options, relating to
- finding `Cargo.toml`, to the command to run.
-
- 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.
-
- The arguments added are
-
- --manifest-path=<path/to/Cargo.toml>
- --locked
- --target-dir=target
+ * `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.)
+ * `!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`.)
+ * `!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 `NAILINGCARGO_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. Primarily for non-cargo build commands.
Environment of the build command
--------------------------------
All of these are absolute paths.
+For out-of-tree builds it is always necessary to pass --manifest-path
+to cargo, so non-cargo build commands will need to look at
+`NAILINGCARGO_MANIFEST_DIR` and turn that back into a cargo option;
+they may also need to pass `--target-dir=<target>`.
+
Configuration reference
=======================
At least, running nailing-cargo again will clean up any mess
left by an interrupted run.
+ * 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 the `-c` option). For other commands, you may need to
+ add an entry to `@subcmd_propss` in the source, or use
+ `--subcommand-props`.
+
* Out of tree builds require a unified filesystem view: eg, different
users on the same host, NFS, or something.
our $worksphere = $src_absdir;
$worksphere =~ s{/([^/]+)$}{}
- or die "$self: cwd \`$worksphere' unsupported!\n";
+ or die "$self: cwd \`$worksphere' unsupported!\n";e
our $subdir = $1; # leafname
our $lockfile = "../.nailing-cargo.lock";
our $cargo_subcmd;
-our $cargo_lock_update;
-our $cargo_manifest_args;
-our $cargo_target_arg=1;
our $alt_cargo_lock;
our $online;
+#
+our %subcmd_props = {
+# build (default) =>qw( ),
+ update =>qw( !target lock-update ),
+'generate-lockfile'=>qw( !target lock-update ),
+ fetch =>qw( !target online !target-dir ),
+ '' =>qw( !target !manifest-path !locked !offline );
+};
+
our @configs;
our $verbose=1;
our ($noact,$dump);
}
sub addargs () {
+ $online = 1 if subcmd_p('online');
$online //= cfg_bool qw(misc online);
-
- if ($cargo_subcmd =~ m/^(?:generate-lockfile|update)$/) {
- $cargo_lock_update //= 1;
- $target = undef;
- }
- if ($cargo_subcmd =~ m/^(?:fetch)$/) {
- $cargo_target_arg=0;
- $online //= 1;
- }
- $cargo_lock_update //= 0;
- $cargo_manifest_args //=
- (defined $oot_dir) && !$cargo_lock_update;
-
$online //= 0;
- if ($cargo_manifest_args) {
- push @ARGV, "--manifest-path=${src_absdir}/Cargo.toml",
- qw(--locked);
- push @ARGV, qw(--target-dir=target) if $cargo_target_arg;
+ $cargo_lock_update //= subcmd_p('lock-update');
+
+ if (!$cargo_lock_update) {
+ push @ARGV, qw(--locked) unless subcmd_p('!locked');
+ if (defined($oot_dir) && !subcmd_p('!manifest-path')) {
+ push @ARGV, "--manifest-path=${src_absdir}/Cargo.toml";
+ push @ARGV, qw(--target-dir=target) unless subcmd_p('!target');
+ }
}
- if (defined $target) {
+ if (defined($target) && !subcmd_p('!target')) {
if ($target =~ m{^[A-Z]}) {
$target = (cfgs 'arch', $target) // $archmap{$target}
// die "$self: --target=$target alias specified; not in cfg or map\n";
push @ARGV, "--target=$target";
}
- push @ARGV, "--offline" unless $online;
+ push @ARGV, "--offline" unless $online || subcmd_p('!offline');
}
our $oot_absdir;
$verbose=0;
} elsif (s{^-n}{-}) {
$noact++;
+ } elsif (s{^-c(.+)}{-}s) {
+ $cargo_subcmd = $1;
+ } elsif (s{^-C}{-}) {
+ $cargo_subcmd = '';
} elsif (s{^-D}{-}) {
$dump++;
- } elsif (s{^-A(.+)}{-}s) {
+ } elsif (s{^-T(.+)}{-}s) {
$target = $1;
- } elsif (s{^-([uU])}{-}) {
- $cargo_lock_update= $1=~m/[a-z]/;
- } elsif (s{^-([mM])}{-}) {
- $cargo_manifest_args= $1=~m/[a-z]/;
- } elsif (s{^-([tT])}{-}) {
- $cargo_target_arg= $1=~m/[a-z]/;
} elsif (s{^-([oO])}{-}) {
$online= $1=~m/[a-z]/;
} else {
$not_a_nailing_opt->();
}
}
- } elsif (s{^--(?:target|arch)=}{}) {
+ } elsif (s{^--target=}{}) {
$target = $_;
- } elsif (m{^--(no-)?cargo-lock-update}) {
- $cargo_lock_update= !!$1;
- } elsif (m{^--(no-)?cargo-manifest-args}) {
- $cargo_manifest_args= !!$1;
- } elsif (m{^--(no-)?cargo-target-dir-arg}) {
- $cargo_target_arg= !!$1;
} elsif (m{^--(on|off)line$}) {
$online = $1 eq 'on';
+ } elsif (s{^--subcommand-props=}{}) {
+ my @props = split /\,/, $_;
+ our %subcmd_prop_ok;
+ if (!%subcmd_prop_ok) {
+ for $v in (%subcmd_props) { $subcmd_prop_ok{$_}=1 foreach @$v; };
+ }
+ $subcmd_prop_ok{$_}
+ or die "$self: unknown subcommand property \`$_'\n"
+ foreach @props;
+ $cargo_subcmd = \@props;
+ } elsif (m{^--(no-)?cargo-lock-update}) {
+ $cargo_lock_update= !!$1;
} else {
$not_a_nailing_opt->();
}
push @cargo_and_opts, $_;
}
@ARGV || die "$self: need cargo subcommand\n";
- $cargo_subcmd = $ARGV[0];
+ $cargo_subcmd //= $ARGV[0];
unshift @ARGV, @cargo_and_opts;
} else {
- $cargo_subcmd = '';
+ $cargo_subcmd //= '';
+ }
+
+ if (!ref($cargo_subcmd)) {
+ $cargo_subcmd = $subcmd_props{$cargo_subcmd} // [ ];
}
}