From 72400c6647ac995814d3d462a4a8c68c7a0cc3ab Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Thu, 7 Oct 2021 09:28:44 -0700 Subject: [PATCH 1/4] RFC: Cargo `--crate-type` CLI Argument --- text/0000-cargo-cli-crate-type.md | 102 ++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 text/0000-cargo-cli-crate-type.md diff --git a/text/0000-cargo-cli-crate-type.md b/text/0000-cargo-cli-crate-type.md new file mode 100644 index 00000000000..a24422ab6f3 --- /dev/null +++ b/text/0000-cargo-cli-crate-type.md @@ -0,0 +1,102 @@ +# RFC: Cargo `--crate-type` CLI Argument + +- Feature Name: `cargo_cli_crate_type` +- Start Date: (fill me in with today's date, YYYY-MM-DD) +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) + +# Summary +[summary]: #summary + +Add the ability to provide `--crate-type ` as an argument to `cargo build`. This would have the same affect of adding `crate-type` in the `Cargo.toml`, while taking higher priority than any value specified there. + +[Previous implementation PR](https://github.com/rust-lang/cargo/pull/8789) + +# Motivation +[motivation]: #motivation + +A crate can declare in its `Cargo.toml` manifest what sort of sort of compilation artifact to produce. However, there are times when the *user* of such a crate, as opposed to the author, would want to alter what artifacts are produced. + +Some crates may provide both a Rust API and an optional C API. A current example is the [hyper](https://github.com/hyperium/hyper) crate. Most users of the Rust API only need an `rlib`, so forcing the compilation of a `cdylib` as well is a waste. It can also cause problems for people including such a crate as a dependency when cross-compiling, or when combining with `-C prefer-dynamic` ([example](https://github.com/rust-lang/rust/issues/82151)). + +Another usecase is sharing a library across different platforms (e.g. iOS, Android, WASM). iOS requires static linking (`staticlib`) [[1]](https://github.com/rust-lang/cargo/issues/4881#issuecomment-732751642), [[2]](https://github.com/rust-lang/rust/pull/77716), Android and WASM require dynamic linking (`cdylib`) and in order to use it as a dependency in Rust requires `rlib`. + +Lastly, being able to pick a specific crate type also decreases build times when you already know which platform you're targeting. + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +When a user builds a library, using `cargo build`, they can provide a `--crate-type` argument to adjust the crate type that is compiled. The argument can be any that can also be listed in the `Cargo.toml`. + +Some examples: + +```shell +cargo build --crate-type staticlib + +cargo build --crate-type cdylib --features ffi +``` + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +A new command-line argument, `--crate-type`, will be added to Cargo. It must be provided a list of 1 or more crate types, of which the allowed values are the same as can be [provided in the manifest](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-crate-type-field). + +The argument will be added for `cargo build` and `cargo rustc`. + +As with the existing `crate-type` manifest property, this will only work when building a `lib` or `example`. + +If the manifest contains a list, and this new command-line argument is provided by the user, the command-line argument value will override what is in the manifest. For example: + +```toml +[lib] +crate-type = ["lib", "staticlib", "cdylib"] +``` + +```shell +cargo build --crate-type staticlib +``` + +This will produce output only as a `staticlib`, ignoring the other values in the manifest. + +# Drawbacks +[drawbacks]: #drawbacks + +The usual reasons to not do this apply here: + +- An additional feature means more surface area to maintain, and more possibility of bugs. +- The Cargo team is already stretched too thin to ask for another feature. However, in this case, an implementation is already written. + +# Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +This gives direct control of the compilation to the end user, instead of making them depend on whatever the crate author put in the `Cargo.toml`. + +An alternative detail to this proposal is to make it so specifying `--crate-type` adds to the list in the `Cargo.toml`, instead of overriding it. However, there would still be a need for end users to override, so there would need to be an additional argument, such as `--no-default-crate-type`. Overriding feels like the less complex solution for a user to comprehend. + +The story around compiling Rust for different targets, and especially in ways that are compatible with C, needs to grow stronger. Choosing not to do this would mean this pain point would continue to exist, which hurts the adoption of writing libraries in Rust instead of C. + +# Prior art +[prior-art]: #prior-art + +There are a couple similar-looking features already in cargo: + +- `--target`: When building a crate, a user can specify the specific target architecture of the compilation output. When not specified, it defaults to the host architecture. +- `--features`: A user can specify a list of features to enable when building a crate directly with `cargo build`. The `Cargo.toml` can provide a default set of features to compile. This differs from the other art, since specifying `--features` will *add* to the default, instead of *overriding* it. + +# Unresolved questions +[unresolved-questions]: #unresolved-questions + +**Should a user be able to configure the crate-type of _all_ crates in the dependency graph?** + +When this feature was first proposed, [it was suggested](https://github.com/rust-lang/cargo/pull/8789#issuecomment-713161246) that a user may wish to configure many dependencies at once, not just the top level crate. This RFC doesn't propose how to solve that, but claims that it can be safely considered out of scope. + +First, such a feature is much larger, and there isn't prior art *in Cargo* to have command-line arguments configuring other dependencies. Designing that would take much more effort. There doesn't seem to be resources available to explore that. + +Additionally, the small focus of the feature proposed in this RFC doesn't prevent that larger design from being explored and added at a later point. Figuring out a way to specify configuration arguments for other dependencies would likely need to work for the existing `--features` argument. Therefore, this isn't a 1-way-door decision, and thus we don't need to stop fixing this particular pain before that is figured out. + +# Future possibilities +[future-possibilities]: #future-possibilities + +The command-line argument may be useful for other `cargo` commands in the future. This RFC starts with a conservative list. + +It may also be of interest to allow a crate "feature" enable different crate-types, such as `--features ffi` enabling `--crate-type cdylib`. From beacf7abe5a15bc825ed45d29ce9f2754463b2a8 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 29 Oct 2021 10:32:45 -0700 Subject: [PATCH 2/4] Update text/0000-cargo-cli-crate-type.md Co-authored-by: Josh Triplett --- text/0000-cargo-cli-crate-type.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-cargo-cli-crate-type.md b/text/0000-cargo-cli-crate-type.md index a24422ab6f3..4cc37d629d7 100644 --- a/text/0000-cargo-cli-crate-type.md +++ b/text/0000-cargo-cli-crate-type.md @@ -39,7 +39,7 @@ cargo build --crate-type cdylib --features ffi # Reference-level explanation [reference-level-explanation]: #reference-level-explanation -A new command-line argument, `--crate-type`, will be added to Cargo. It must be provided a list of 1 or more crate types, of which the allowed values are the same as can be [provided in the manifest](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-crate-type-field). +A new command-line argument, `--crate-type`, will be added to Cargo. It must be provided a comma-separated list of 1 or more crate types, of which the allowed values are the same as can be [provided in the manifest](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-crate-type-field). The argument will be added for `cargo build` and `cargo rustc`. From bc2088e53a1877697a65da929b630dd025ad6c10 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Tue, 2 Nov 2021 15:06:43 -0700 Subject: [PATCH 3/4] change to 'cargo rustc' --- text/0000-cargo-cli-crate-type.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/text/0000-cargo-cli-crate-type.md b/text/0000-cargo-cli-crate-type.md index 4cc37d629d7..02636328597 100644 --- a/text/0000-cargo-cli-crate-type.md +++ b/text/0000-cargo-cli-crate-type.md @@ -8,7 +8,7 @@ # Summary [summary]: #summary -Add the ability to provide `--crate-type ` as an argument to `cargo build`. This would have the same affect of adding `crate-type` in the `Cargo.toml`, while taking higher priority than any value specified there. +Add the ability to provide `--crate-type ` as an argument to `cargo rustc`. This would have the same affect of adding `crate-type` in the `Cargo.toml`, while taking higher priority than any value specified there. [Previous implementation PR](https://github.com/rust-lang/cargo/pull/8789) @@ -26,14 +26,14 @@ Lastly, being able to pick a specific crate type also decreases build times when # Guide-level explanation [guide-level-explanation]: #guide-level-explanation -When a user builds a library, using `cargo build`, they can provide a `--crate-type` argument to adjust the crate type that is compiled. The argument can be any that can also be listed in the `Cargo.toml`. +When a user builds a library, using `cargo rustc`, they can provide a `--crate-type` argument to adjust the crate type that is compiled. The argument can be any that can also be listed in the `Cargo.toml`. Some examples: ```shell -cargo build --crate-type staticlib +cargo rustc --crate-type staticlib -cargo build --crate-type cdylib --features ffi +cargo rustc --crate-type cdylib --features ffi ``` # Reference-level explanation @@ -41,7 +41,7 @@ cargo build --crate-type cdylib --features ffi A new command-line argument, `--crate-type`, will be added to Cargo. It must be provided a comma-separated list of 1 or more crate types, of which the allowed values are the same as can be [provided in the manifest](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-crate-type-field). -The argument will be added for `cargo build` and `cargo rustc`. +The argument will be added for `cargo rustc`. As with the existing `crate-type` manifest property, this will only work when building a `lib` or `example`. @@ -53,7 +53,7 @@ crate-type = ["lib", "staticlib", "cdylib"] ``` ```shell -cargo build --crate-type staticlib +cargo rustc --crate-type staticlib ``` This will produce output only as a `staticlib`, ignoring the other values in the manifest. From ac3ac32025948c4e8ce403c02cbe53a91eb290b4 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sun, 14 Nov 2021 11:35:24 -0800 Subject: [PATCH 4/4] Update RFC 3180 to merge. --- ...cargo-cli-crate-type.md => 3180-cargo-cli-crate-type.md} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename text/{0000-cargo-cli-crate-type.md => 3180-cargo-cli-crate-type.md} (96%) diff --git a/text/0000-cargo-cli-crate-type.md b/text/3180-cargo-cli-crate-type.md similarity index 96% rename from text/0000-cargo-cli-crate-type.md rename to text/3180-cargo-cli-crate-type.md index 02636328597..3489a266e66 100644 --- a/text/0000-cargo-cli-crate-type.md +++ b/text/3180-cargo-cli-crate-type.md @@ -1,9 +1,9 @@ # RFC: Cargo `--crate-type` CLI Argument - Feature Name: `cargo_cli_crate_type` -- Start Date: (fill me in with today's date, YYYY-MM-DD) -- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) -- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) +- Start Date: 2021-10-07 +- RFC PR: [rust-lang/rfcs#3180](https://github.com/rust-lang/rfcs/pull/3180) +- Tracking Issue: [rust-lang/cargo#10083](https://github.com/rust-lang/cargo/issues/10083) # Summary [summary]: #summary