Skip to content

Commit b85ad15

Browse files
committed
Auto merge of #10093 - hi-rustin:rustin-patch-rustc, r=ehuss
Add crate type flag to rustc command part of #10083 - Add crate type flag to rustc command - Add tests - Update docs
2 parents 7f08ace + 137f9bc commit b85ad15

File tree

8 files changed

+309
-4
lines changed

8 files changed

+309
-4
lines changed

src/bin/cargo/commands/rustc.rs

+18-2
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+
"Comma separated list of types of crates for the compiler to emit (unstable)",
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

+9
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

+13-2
Original file line numberDiff line numberDiff line change
@@ -861,9 +861,20 @@ fn build_base_args(
861861
add_error_format_and_color(cx, cmd, cx.rmeta_required(unit));
862862
add_allow_features(cx, cmd);
863863

864+
let mut contains_dy_lib = false;
864865
if !test {
866+
let mut crate_types = &crate_types
867+
.iter()
868+
.map(|t| t.as_str().to_string())
869+
.collect::<Vec<String>>();
870+
if let Some(types) = cx.bcx.rustc_crate_types_args_for(unit) {
871+
crate_types = types;
872+
}
865873
for crate_type in crate_types.iter() {
866-
cmd.arg("--crate-type").arg(crate_type.as_str());
874+
cmd.arg("--crate-type").arg(crate_type);
875+
if crate_type == CrateType::Dylib.as_str() {
876+
contains_dy_lib = true;
877+
}
867878
}
868879
}
869880

@@ -879,7 +890,7 @@ fn build_base_args(
879890
}
880891

881892
let prefer_dynamic = (unit.target.for_host() && !unit.target.is_custom_build())
882-
|| (crate_types.contains(&CrateType::Dylib) && !cx.is_primary_package(unit));
893+
|| (contains_dy_lib && !cx.is_primary_package(unit));
883894
if prefer_dynamic {
884895
cmd.arg("-C").arg("prefer-dynamic");
885896
}

src/cargo/ops/cargo_compile.rs

+27
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ 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+
/// Crate types to be passed to rustc (single target only)
75+
pub target_rustc_crate_types: Option<Vec<String>>,
7476
/// Extra arguments passed to all selected targets for rustdoc.
7577
pub local_rustdoc_args: Option<Vec<String>>,
7678
/// Whether the `--document-private-items` flags was specified and should
@@ -92,6 +94,7 @@ impl<'a> CompileOptions {
9294
},
9395
target_rustdoc_args: None,
9496
target_rustc_args: None,
97+
target_rustc_crate_types: None,
9598
local_rustdoc_args: None,
9699
rustdoc_document_private_items: false,
97100
honor_rust_version: true,
@@ -332,6 +335,7 @@ pub fn create_bcx<'a, 'cfg>(
332335
ref filter,
333336
ref target_rustdoc_args,
334337
ref target_rustc_args,
338+
ref target_rustc_crate_types,
335339
ref local_rustdoc_args,
336340
rustdoc_document_private_items,
337341
honor_rust_version,
@@ -644,6 +648,28 @@ pub fn create_bcx<'a, 'cfg>(
644648
}
645649
}
646650

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

src/cargo/ops/cargo_package.rs

+1
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

+1
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"),

src/doc/src/reference/unstable.md

+18
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ Each new feature described below should explain how to use it.
8383
* [build-std-features](#build-std-features) — Sets features to use with the standard library.
8484
* [binary-dep-depinfo](#binary-dep-depinfo) — Causes the dep-info file to track binary dependencies.
8585
* [panic-abort-tests](#panic-abort-tests) — Allows running tests with the "abort" panic strategy.
86+
* [crate-type](#crate-type) - Supports passing crate types to the compiler.
8687
* rustdoc
8788
* [`doctest-in-workspace`](#doctest-in-workspace) — Fixes workspace-relative paths when running doctests.
8889
* [rustdoc-map](#rustdoc-map) — Provides mappings for documentation to link to external sites like [docs.rs](https://docs.rs/).
@@ -555,6 +556,23 @@ like to stabilize it somehow!
555556

556557
[rust-lang/rust#64158]: https://github.com/rust-lang/rust/pull/64158
557558

559+
### crate-type
560+
* Tracking Issue: [#10083](https://github.com/rust-lang/cargo/issues/10083)
561+
* RFC: [#3180](https://github.com/rust-lang/rfcs/pull/3180)
562+
* Original Pull Request: [#10093](https://github.com/rust-lang/cargo/pull/10093)
563+
564+
`cargo rustc --crate-type=lib,cdylib` forwards the `--crate-type` flag to `rustc`.
565+
This runs `rustc` with the corresponding
566+
[`--crate-type`](https://doc.rust-lang.org/rustc/command-line-arguments.html#--crate-type-a-list-of-types-of-crates-for-the-compiler-to-emit)
567+
flag, and compiling.
568+
569+
When using it, it requires the `-Z unstable-options`
570+
command-line option:
571+
572+
```console
573+
cargo rustc --crate-type lib,cdylib -Z unstable-options
574+
```
575+
558576
### config-cli
559577
* Tracking Issue: [#7722](https://github.com/rust-lang/cargo/issues/7722)
560578

0 commit comments

Comments
 (0)