From 0c5f348bc2b62a058fa7c7176b80ea3367ef50b4 Mon Sep 17 00:00:00 2001 From: hi-rustin Date: Wed, 17 Nov 2021 20:34:44 +0800 Subject: [PATCH] Add crate type flag to rustc command Signed-off-by: hi-rustin --- src/bin/cargo/commands/rustc.rs | 20 +++++++++++++-- src/cargo/core/compiler/build_context/mod.rs | 9 +++++++ src/cargo/core/compiler/mod.rs | 10 ++++++-- src/cargo/ops/cargo_compile.rs | 26 ++++++++++++++++++++ src/cargo/ops/cargo_package.rs | 1 + src/cargo/util/command_prelude.rs | 1 + 6 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/bin/cargo/commands/rustc.rs b/src/bin/cargo/commands/rustc.rs index d5c6945b6f7..b79bdb9ddf3 100644 --- a/src/bin/cargo/commands/rustc.rs +++ b/src/bin/cargo/commands/rustc.rs @@ -3,6 +3,7 @@ use cargo::ops; use cargo::util::interning::InternedString; const PRINT_ARG_NAME: &str = "print"; +const CRATE_TYPE_ARG_NAME: &str = "crate-type"; pub fn cli() -> App { subcommand("rustc") @@ -35,6 +36,11 @@ pub fn cli() -> App { ) .value_name("INFO"), ) + .arg(multi_opt( + CRATE_TYPE_ARG_NAME, + "CRATE-TYPE", + "Rustc crate-types", + )) .arg_target_dir() .arg_manifest_path() .arg_message_format() @@ -75,8 +81,18 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { .cli_unstable() .fail_if_stable_opt(PRINT_ARG_NAME, 9357)?; ops::print(&ws, &compile_opts, opt_value)?; - } else { - ops::compile(&ws, &compile_opts)?; + return Ok(()); } + let crate_types = values(args, CRATE_TYPE_ARG_NAME); + compile_opts.target_rustc_crate_types = if crate_types.is_empty() { + None + } else { + config + .cli_unstable() + .fail_if_stable_opt(CRATE_TYPE_ARG_NAME, 10083)?; + Some(crate_types) + }; + ops::compile(&ws, &compile_opts)?; + Ok(()) } diff --git a/src/cargo/core/compiler/build_context/mod.rs b/src/cargo/core/compiler/build_context/mod.rs index 624a6e88ae6..9141314a9c7 100644 --- a/src/cargo/core/compiler/build_context/mod.rs +++ b/src/cargo/core/compiler/build_context/mod.rs @@ -33,6 +33,9 @@ pub struct BuildContext<'a, 'cfg> { /// Extra compiler args for either `rustc` or `rustdoc`. pub extra_compiler_args: HashMap>, + // Crate types for `rustc`. + pub target_rustc_crate_types: HashMap>, + /// Package downloader. /// /// This holds ownership of the `Package` objects. @@ -61,6 +64,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> { build_config: &'a BuildConfig, profiles: Profiles, extra_compiler_args: HashMap>, + target_rustc_crate_types: HashMap>, target_data: RustcTargetData<'cfg>, roots: Vec, unit_graph: UnitGraph, @@ -80,6 +84,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> { build_config, profiles, extra_compiler_args, + target_rustc_crate_types, target_data, roots, unit_graph, @@ -127,4 +132,8 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> { pub fn extra_args_for(&self, unit: &Unit) -> Option<&Vec> { self.extra_compiler_args.get(unit) } + + pub fn rustc_crate_types_args_for(&self, unit: &Unit) -> Option<&Vec> { + self.target_rustc_crate_types.get(unit) + } } diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 884f1efc367..08a3261b860 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -862,8 +862,14 @@ fn build_base_args( add_allow_features(cx, cmd); if !test { - for crate_type in crate_types.iter() { - cmd.arg("--crate-type").arg(crate_type.as_str()); + 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()); + } } } diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 392cef74085..56c21d30d70 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>, + pub target_rustc_crate_types: Option>, /// Extra arguments passed to all selected targets for rustdoc. pub local_rustdoc_args: Option>, /// Whether the `--document-private-items` flags was specified and should @@ -92,6 +93,7 @@ impl<'a> CompileOptions { }, target_rustdoc_args: None, target_rustc_args: None, + target_rustc_crate_types: None, local_rustdoc_args: None, rustdoc_document_private_items: false, honor_rust_version: true, @@ -332,6 +334,7 @@ pub fn create_bcx<'a, 'cfg>( ref filter, ref target_rustdoc_args, ref target_rustc_args, + ref target_rustc_crate_types, ref local_rustdoc_args, rustdoc_document_private_items, honor_rust_version, @@ -644,6 +647,28 @@ pub fn create_bcx<'a, 'cfg>( } } + let mut crate_types = HashMap::new(); + if let Some(args) = target_rustc_crate_types { + if units.len() != 1 { + 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" + ); + } + match units[0].target.kind() { + TargetKind::Lib(_) | TargetKind::ExampleLib(_) => { + crate_types.insert(units[0].clone(), args.clone()); + } + _ => { + anyhow::bail!( + "crate types can only be specified for libraries and examples. \ + Binaries, tests, and benchmarks are always the `bin` crate type" + ); + } + } + } + if honor_rust_version { // Remove any pre-release identifiers for easier comparison let current_version = &target_data.rustc.version; @@ -680,6 +705,7 @@ pub fn create_bcx<'a, 'cfg>( build_config, profiles, extra_compiler_args, + crate_types, target_data, units, unit_graph, diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 48477ea25e0..ed264079bec 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -763,6 +763,7 @@ fn run_verify( }, target_rustdoc_args: None, target_rustc_args: rustc_args, + target_rustc_crate_types: None, local_rustdoc_args: None, rustdoc_document_private_items: false, honor_rust_version: true, diff --git a/src/cargo/util/command_prelude.rs b/src/cargo/util/command_prelude.rs index 7389ec56e39..066e900ad46 100644 --- a/src/cargo/util/command_prelude.rs +++ b/src/cargo/util/command_prelude.rs @@ -542,6 +542,7 @@ pub trait ArgMatchesExt { ), target_rustdoc_args: None, target_rustc_args: None, + target_rustc_crate_types: None, local_rustdoc_args: None, rustdoc_document_private_items: false, honor_rust_version: !self._is_present("ignore-rust-version"),