From 660ce6bba45b8b9b495fd22e4dedcdb637a86d34 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Thu, 18 Nov 2021 23:57:42 +0800 Subject: [PATCH] Add tests Signed-off-by: hi-rustin --- src/bin/cargo/commands/rustc.rs | 2 +- src/cargo/core/compiler/mod.rs | 21 +-- src/cargo/ops/cargo_compile.rs | 5 +- tests/testsuite/rustc.rs | 222 ++++++++++++++++++++++++++++++++ 4 files changed, 239 insertions(+), 11 deletions(-) diff --git a/src/bin/cargo/commands/rustc.rs b/src/bin/cargo/commands/rustc.rs index b79bdb9ddf3..54b4e205ab5 100644 --- a/src/bin/cargo/commands/rustc.rs +++ b/src/bin/cargo/commands/rustc.rs @@ -39,7 +39,7 @@ pub fn cli() -> App { .arg(multi_opt( CRATE_TYPE_ARG_NAME, "CRATE-TYPE", - "Rustc crate-types", + "Comma separated list of types of crates for the compiler to emit (unstable)", )) .arg_target_dir() .arg_manifest_path() diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 08a3261b860..cb9b3c681ab 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -861,14 +861,19 @@ fn build_base_args( 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::>(); + 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; } } } @@ -885,7 +890,7 @@ fn build_base_args( } 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"); } diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 56c21d30d70..81b43124a18 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -71,6 +71,7 @@ pub struct CompileOptions { /// 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>, + /// Crate types to be passed to rustc (single target only) pub target_rustc_crate_types: Option>, /// Extra arguments passed to all selected targets for rustdoc. pub local_rustdoc_args: Option>, @@ -653,7 +654,7 @@ pub fn create_bcx<'a, 'cfg>( 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() { @@ -662,7 +663,7 @@ pub fn create_bcx<'a, 'cfg>( } _ => { 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" ); } diff --git a/tests/testsuite/rustc.rs b/tests/testsuite/rustc.rs index 53b5c6fb19a..571e5392783 100644 --- a/tests/testsuite/rustc.rs +++ b/tests/testsuite/rustc.rs @@ -134,6 +134,228 @@ fn fails_with_args_to_all_binaries() { .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()