add_error_format_and_color(cx, cmd, cx.rmeta_required(unit));
add_allow_features(cx, cmd);
+ let mut contains_dy_lib = false;
if !test {
- if let Some(crate_types) = cx.bcx.rustc_crate_types_args_for(unit) {
- for crate_type in crate_types.iter() {
- cmd.arg("--crate-type").arg(crate_type);
- }
- } else {
- for crate_type in crate_types.iter() {
- cmd.arg("--crate-type").arg(crate_type.as_str());
+ let mut crate_types = &crate_types
+ .iter()
+ .map(|t| t.as_str().to_string())
+ .collect::<Vec<String>>();
+ if let Some(types) = cx.bcx.rustc_crate_types_args_for(unit) {
+ crate_types = types;
+ }
+ for crate_type in crate_types.iter() {
+ cmd.arg("--crate-type").arg(crate_type);
+ if crate_type == CrateType::Dylib.as_str() {
+ contains_dy_lib = true;
}
}
}
}
let prefer_dynamic = (unit.target.for_host() && !unit.target.is_custom_build())
- || (crate_types.contains(&CrateType::Dylib) && !cx.is_primary_package(unit));
+ || (contains_dy_lib && !cx.is_primary_package(unit));
if prefer_dynamic {
cmd.arg("-C").arg("prefer-dynamic");
}
/// The specified target will be compiled with all the available arguments,
/// note that this only accounts for the *final* invocation of rustc
pub target_rustc_args: Option<Vec<String>>,
+ /// Crate types to be passed to rustc (single target only)
pub target_rustc_crate_types: Option<Vec<String>>,
/// Extra arguments passed to all selected targets for rustdoc.
pub local_rustdoc_args: Option<Vec<String>>,
anyhow::bail!(
"crate types to rustc can only be passed to one \
target, consider filtering\nthe package by passing, \
- e.g., `--lib` to specify a single target"
+ e.g., `--lib` or `--example` to specify a single target"
);
}
match units[0].target.kind() {
}
_ => {
anyhow::bail!(
- "crate types can only be specified for libraries and examples. \
+ "crate types can only be specified for libraries and example libraries.\n\
Binaries, tests, and benchmarks are always the `bin` crate type"
);
}
.run();
}
+#[cargo_test]
+fn fails_with_crate_type_and_without_unstable_options() {
+ let p = project().file("src/lib.rs", r#" "#).build();
+
+ p.cargo("rustc --crate-type lib")
+ .masquerade_as_nightly_cargo()
+ .with_status(101)
+ .with_stderr(
+ "[ERROR] the `crate-type` flag is unstable, pass `-Z unstable-options` to enable it
+See https://github.com/rust-lang/cargo/issues/10083 for more information about the `crate-type` flag.",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn fails_with_crate_type_to_multi_binaries() {
+ let p = project()
+ .file("src/bin/foo.rs", "fn main() {}")
+ .file("src/bin/bar.rs", "fn main() {}")
+ .file("src/bin/baz.rs", "fn main() {}")
+ .file("src/lib.rs", r#" "#)
+ .build();
+
+ p.cargo("rustc --crate-type lib -Zunstable-options")
+ .masquerade_as_nightly_cargo()
+ .with_status(101)
+ .with_stderr(
+ "[ERROR] crate types to rustc can only be passed to one target, consider filtering
+the package by passing, e.g., `--lib` or `--example` to specify a single target",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn fails_with_crate_type_to_multi_examples() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[example]]
+ name = "ex1"
+ crate-type = ["rlib"]
+ [[example]]
+ name = "ex2"
+ crate-type = ["rlib"]
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("examples/ex1.rs", "")
+ .file("examples/ex2.rs", "")
+ .build();
+
+ p.cargo("rustc -v --example ex1 --example ex2 --crate-type lib,cdylib -Zunstable-options")
+ .masquerade_as_nightly_cargo()
+ .with_status(101)
+ .with_stderr(
+ "[ERROR] crate types to rustc can only be passed to one target, consider filtering
+the package by passing, e.g., `--lib` or `--example` to specify a single target",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn fails_with_crate_type_to_binary() {
+ let p = project().file("src/bin/foo.rs", "fn main() {}").build();
+
+ p.cargo("rustc --crate-type lib -Zunstable-options")
+ .masquerade_as_nightly_cargo()
+ .with_status(101)
+ .with_stderr(
+ "[ERROR] crate types can only be specified for libraries and example libraries.
+Binaries, tests, and benchmarks are always the `bin` crate type",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_with_crate_type_for_foo() {
+ let p = project()
+ .file("src/main.rs", "fn main() {}")
+ .file("src/lib.rs", r#" "#)
+ .build();
+
+ p.cargo("rustc -v --lib --crate-type lib -Zunstable-options")
+ .masquerade_as_nightly_cargo()
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib [..]
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_with_crate_types_for_foo() {
+ let p = project()
+ .file("src/main.rs", "fn main() {}")
+ .file("src/lib.rs", r#" "#)
+ .build();
+
+ p.cargo("rustc -v --lib --crate-type lib,cdylib -Zunstable-options")
+ .masquerade_as_nightly_cargo()
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib,cdylib [..]
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_with_crate_type_to_example() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[example]]
+ name = "ex"
+ crate-type = ["rlib"]
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("examples/ex.rs", "")
+ .build();
+
+ p.cargo("rustc -v --example ex --crate-type cdylib -Zunstable-options")
+ .masquerade_as_nightly_cargo()
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib [..]
+[RUNNING] `rustc --crate-name ex examples/ex.rs [..]--crate-type cdylib [..]
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_with_crate_types_to_example() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[example]]
+ name = "ex"
+ crate-type = ["rlib"]
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("examples/ex.rs", "")
+ .build();
+
+ p.cargo("rustc -v --example ex --crate-type lib,cdylib -Zunstable-options")
+ .masquerade_as_nightly_cargo()
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib [..]
+[RUNNING] `rustc --crate-name ex examples/ex.rs [..]--crate-type lib,cdylib [..]
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+",
+ )
+ .run();
+}
+
+#[cargo_test]
+fn build_with_crate_types_to_one_of_multi_examples() {
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [[example]]
+ name = "ex1"
+ crate-type = ["rlib"]
+ [[example]]
+ name = "ex2"
+ crate-type = ["rlib"]
+ "#,
+ )
+ .file("src/lib.rs", "")
+ .file("examples/ex1.rs", "")
+ .file("examples/ex2.rs", "")
+ .build();
+
+ p.cargo("rustc -v --example ex1 --crate-type lib,cdylib -Zunstable-options")
+ .masquerade_as_nightly_cargo()
+ .with_stderr(
+ "\
+[COMPILING] foo v0.0.1 ([CWD])
+[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib [..]
+[RUNNING] `rustc --crate-name ex1 examples/ex1.rs [..]--crate-type lib,cdylib [..]
+[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
+",
+ )
+ .run();
+}
+
#[cargo_test]
fn build_with_args_to_one_of_multiple_tests() {
let p = project()