Skip to content

Commit 0c5f348

Browse files
committed
Add crate type flag to rustc command
Signed-off-by: hi-rustin <[email protected]>
1 parent e475fe4 commit 0c5f348

File tree

6 files changed

+63
-4
lines changed

6 files changed

+63
-4
lines changed

src/bin/cargo/commands/rustc.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use cargo::ops;
33
use cargo::util::interning::InternedString;
44

55
const PRINT_ARG_NAME: &str = "print";
6+
const CRATE_TYPE_ARG_NAME: &str = "crate-type";
67

78
pub fn cli() -> App {
89
subcommand("rustc")
@@ -35,6 +36,11 @@ pub fn cli() -> App {
3536
)
3637
.value_name("INFO"),
3738
)
39+
.arg(multi_opt(
40+
CRATE_TYPE_ARG_NAME,
41+
"CRATE-TYPE",
42+
"Rustc crate-types",
43+
))
3844
.arg_target_dir()
3945
.arg_manifest_path()
4046
.arg_message_format()
@@ -75,8 +81,18 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
7581
.cli_unstable()
7682
.fail_if_stable_opt(PRINT_ARG_NAME, 9357)?;
7783
ops::print(&ws, &compile_opts, opt_value)?;
78-
} else {
79-
ops::compile(&ws, &compile_opts)?;
84+
return Ok(());
8085
}
86+
let crate_types = values(args, CRATE_TYPE_ARG_NAME);
87+
compile_opts.target_rustc_crate_types = if crate_types.is_empty() {
88+
None
89+
} else {
90+
config
91+
.cli_unstable()
92+
.fail_if_stable_opt(CRATE_TYPE_ARG_NAME, 10083)?;
93+
Some(crate_types)
94+
};
95+
ops::compile(&ws, &compile_opts)?;
96+
8197
Ok(())
8298
}

src/cargo/core/compiler/build_context/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ pub struct BuildContext<'a, 'cfg> {
3333
/// Extra compiler args for either `rustc` or `rustdoc`.
3434
pub extra_compiler_args: HashMap<Unit, Vec<String>>,
3535

36+
// Crate types for `rustc`.
37+
pub target_rustc_crate_types: HashMap<Unit, Vec<String>>,
38+
3639
/// Package downloader.
3740
///
3841
/// This holds ownership of the `Package` objects.
@@ -61,6 +64,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
6164
build_config: &'a BuildConfig,
6265
profiles: Profiles,
6366
extra_compiler_args: HashMap<Unit, Vec<String>>,
67+
target_rustc_crate_types: HashMap<Unit, Vec<String>>,
6468
target_data: RustcTargetData<'cfg>,
6569
roots: Vec<Unit>,
6670
unit_graph: UnitGraph,
@@ -80,6 +84,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
8084
build_config,
8185
profiles,
8286
extra_compiler_args,
87+
target_rustc_crate_types,
8388
target_data,
8489
roots,
8590
unit_graph,
@@ -127,4 +132,8 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
127132
pub fn extra_args_for(&self, unit: &Unit) -> Option<&Vec<String>> {
128133
self.extra_compiler_args.get(unit)
129134
}
135+
136+
pub fn rustc_crate_types_args_for(&self, unit: &Unit) -> Option<&Vec<String>> {
137+
self.target_rustc_crate_types.get(unit)
138+
}
130139
}

src/cargo/core/compiler/mod.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -862,8 +862,14 @@ fn build_base_args(
862862
add_allow_features(cx, cmd);
863863

864864
if !test {
865-
for crate_type in crate_types.iter() {
866-
cmd.arg("--crate-type").arg(crate_type.as_str());
865+
if let Some(crate_types) = cx.bcx.rustc_crate_types_args_for(unit) {
866+
for crate_type in crate_types.iter() {
867+
cmd.arg("--crate-type").arg(crate_type);
868+
}
869+
} else {
870+
for crate_type in crate_types.iter() {
871+
cmd.arg("--crate-type").arg(crate_type.as_str());
872+
}
867873
}
868874
}
869875

src/cargo/ops/cargo_compile.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ pub struct CompileOptions {
7171
/// The specified target will be compiled with all the available arguments,
7272
/// note that this only accounts for the *final* invocation of rustc
7373
pub target_rustc_args: Option<Vec<String>>,
74+
pub target_rustc_crate_types: Option<Vec<String>>,
7475
/// Extra arguments passed to all selected targets for rustdoc.
7576
pub local_rustdoc_args: Option<Vec<String>>,
7677
/// Whether the `--document-private-items` flags was specified and should
@@ -92,6 +93,7 @@ impl<'a> CompileOptions {
9293
},
9394
target_rustdoc_args: None,
9495
target_rustc_args: None,
96+
target_rustc_crate_types: None,
9597
local_rustdoc_args: None,
9698
rustdoc_document_private_items: false,
9799
honor_rust_version: true,
@@ -332,6 +334,7 @@ pub fn create_bcx<'a, 'cfg>(
332334
ref filter,
333335
ref target_rustdoc_args,
334336
ref target_rustc_args,
337+
ref target_rustc_crate_types,
335338
ref local_rustdoc_args,
336339
rustdoc_document_private_items,
337340
honor_rust_version,
@@ -644,6 +647,28 @@ pub fn create_bcx<'a, 'cfg>(
644647
}
645648
}
646649

650+
let mut crate_types = HashMap::new();
651+
if let Some(args) = target_rustc_crate_types {
652+
if units.len() != 1 {
653+
anyhow::bail!(
654+
"crate types to rustc can only be passed to one \
655+
target, consider filtering\nthe package by passing, \
656+
e.g., `--lib` to specify a single target"
657+
);
658+
}
659+
match units[0].target.kind() {
660+
TargetKind::Lib(_) | TargetKind::ExampleLib(_) => {
661+
crate_types.insert(units[0].clone(), args.clone());
662+
}
663+
_ => {
664+
anyhow::bail!(
665+
"crate types can only be specified for libraries and examples. \
666+
Binaries, tests, and benchmarks are always the `bin` crate type"
667+
);
668+
}
669+
}
670+
}
671+
647672
if honor_rust_version {
648673
// Remove any pre-release identifiers for easier comparison
649674
let current_version = &target_data.rustc.version;
@@ -680,6 +705,7 @@ pub fn create_bcx<'a, 'cfg>(
680705
build_config,
681706
profiles,
682707
extra_compiler_args,
708+
crate_types,
683709
target_data,
684710
units,
685711
unit_graph,

src/cargo/ops/cargo_package.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,7 @@ fn run_verify(
763763
},
764764
target_rustdoc_args: None,
765765
target_rustc_args: rustc_args,
766+
target_rustc_crate_types: None,
766767
local_rustdoc_args: None,
767768
rustdoc_document_private_items: false,
768769
honor_rust_version: true,

src/cargo/util/command_prelude.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,7 @@ pub trait ArgMatchesExt {
542542
),
543543
target_rustdoc_args: None,
544544
target_rustc_args: None,
545+
target_rustc_crate_types: None,
545546
local_rustdoc_args: None,
546547
rustdoc_document_private_items: false,
547548
honor_rust_version: !self._is_present("ignore-rust-version"),

0 commit comments

Comments
 (0)