Skip to content

Commit 1e55490

Browse files
committed
Auto merge of #10388 - weihanglo:issue-10356, r=ehuss
Override target crate-type for `cargo rustc --crate-type`
2 parents 188298f + b833643 commit 1e55490

File tree

4 files changed

+98
-54
lines changed

4 files changed

+98
-54
lines changed

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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ 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-
3936
/// Package downloader.
4037
///
4138
/// This holds ownership of the `Package` objects.
@@ -64,7 +61,6 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
6461
build_config: &'a BuildConfig,
6562
profiles: Profiles,
6663
extra_compiler_args: HashMap<Unit, Vec<String>>,
67-
target_rustc_crate_types: HashMap<Unit, Vec<String>>,
6864
target_data: RustcTargetData<'cfg>,
6965
roots: Vec<Unit>,
7066
unit_graph: UnitGraph,
@@ -84,7 +80,6 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
8480
build_config,
8581
profiles,
8682
extra_compiler_args,
87-
target_rustc_crate_types,
8883
target_data,
8984
roots,
9085
unit_graph,
@@ -132,8 +127,4 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
132127
pub fn extra_args_for(&self, unit: &Unit) -> Option<&Vec<String>> {
133128
self.extra_compiler_args.get(unit)
134129
}
135-
136-
pub fn rustc_crate_types_args_for(&self, unit: &Unit) -> Option<&Vec<String>> {
137-
self.target_rustc_crate_types.get(unit)
138-
}
139130
}

src/cargo/core/compiler/mod.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -890,18 +890,9 @@ fn build_base_args(
890890

891891
let mut contains_dy_lib = false;
892892
if !test {
893-
let mut crate_types = &crate_types
894-
.iter()
895-
.map(|t| t.as_str().to_string())
896-
.collect::<Vec<String>>();
897-
if let Some(types) = cx.bcx.rustc_crate_types_args_for(unit) {
898-
crate_types = types;
899-
}
900-
for crate_type in crate_types.iter() {
901-
cmd.arg("--crate-type").arg(crate_type);
902-
if crate_type == CrateType::Dylib.as_str() {
903-
contains_dy_lib = true;
904-
}
893+
for crate_type in crate_types {
894+
cmd.arg("--crate-type").arg(crate_type.as_str());
895+
contains_dy_lib |= crate_type == &CrateType::Dylib;
905896
}
906897
}
907898

src/cargo/ops/cargo_compile.rs

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use std::sync::Arc;
2828

2929
use crate::core::compiler::unit_dependencies::{build_unit_dependencies, IsArtifact};
3030
use crate::core::compiler::unit_graph::{self, UnitDep, UnitGraph};
31-
use crate::core::compiler::{standard_lib, TargetInfo};
31+
use crate::core::compiler::{standard_lib, CrateType, TargetInfo};
3232
use crate::core::compiler::{BuildConfig, BuildContext, Compilation, Context};
3333
use crate::core::compiler::{CompileKind, CompileMode, CompileTarget, RustcTargetData, Unit};
3434
use crate::core::compiler::{DefaultExecutor, Executor, UnitInterner};
@@ -505,6 +505,10 @@ pub fn create_bcx<'a, 'cfg>(
505505
interner,
506506
)?;
507507

508+
if let Some(args) = target_rustc_crate_types {
509+
override_rustc_crate_types(&mut units, args, interner)?;
510+
}
511+
508512
let mut scrape_units = match rustdoc_scrape_examples {
509513
Some(arg) => {
510514
let filter = match arg.as_str() {
@@ -648,28 +652,6 @@ pub fn create_bcx<'a, 'cfg>(
648652
}
649653
}
650654

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-
673655
if honor_rust_version {
674656
// Remove any pre-release identifiers for easier comparison
675657
let current_version = &target_data.rustc.version;
@@ -706,7 +688,6 @@ pub fn create_bcx<'a, 'cfg>(
706688
build_config,
707689
profiles,
708690
extra_compiler_args,
709-
crate_types,
710691
target_data,
711692
units,
712693
unit_graph,
@@ -1871,3 +1852,50 @@ fn remove_duplicate_doc(
18711852
}
18721853
unit_graph.retain(|unit, _| visited.contains(unit));
18731854
}
1855+
1856+
/// Override crate types for given units.
1857+
///
1858+
/// This is primarily used by `cargo rustc --crate-type`.
1859+
fn override_rustc_crate_types(
1860+
units: &mut [Unit],
1861+
args: &[String],
1862+
interner: &UnitInterner,
1863+
) -> CargoResult<()> {
1864+
if units.len() != 1 {
1865+
anyhow::bail!(
1866+
"crate types to rustc can only be passed to one \
1867+
target, consider filtering\nthe package by passing, \
1868+
e.g., `--lib` or `--example` to specify a single target"
1869+
);
1870+
}
1871+
1872+
let unit = &units[0];
1873+
let override_unit = |f: fn(Vec<CrateType>) -> TargetKind| {
1874+
let crate_types = args.iter().map(|s| s.into()).collect();
1875+
let mut target = unit.target.clone();
1876+
target.set_kind(f(crate_types));
1877+
interner.intern(
1878+
&unit.pkg,
1879+
&target,
1880+
unit.profile.clone(),
1881+
unit.kind,
1882+
unit.mode,
1883+
unit.features.clone(),
1884+
unit.is_std,
1885+
unit.dep_hash,
1886+
unit.artifact,
1887+
)
1888+
};
1889+
units[0] = match unit.target.kind() {
1890+
TargetKind::Lib(_) => override_unit(TargetKind::Lib),
1891+
TargetKind::ExampleLib(_) => override_unit(TargetKind::ExampleLib),
1892+
_ => {
1893+
anyhow::bail!(
1894+
"crate types can only be specified for libraries and example libraries.\n\
1895+
Binaries, tests, and benchmarks are always the `bin` crate type"
1896+
);
1897+
}
1898+
};
1899+
1900+
Ok(())
1901+
}

tests/testsuite/rustc.rs

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -217,17 +217,54 @@ Binaries, tests, and benchmarks are always the `bin` crate type",
217217

218218
#[cargo_test]
219219
fn build_with_crate_type_for_foo() {
220+
let p = project().file("src/lib.rs", "").build();
221+
222+
p.cargo("rustc -v --crate-type cdylib -Zunstable-options")
223+
.masquerade_as_nightly_cargo()
224+
.with_stderr(
225+
"\
226+
[COMPILING] foo v0.0.1 ([CWD])
227+
[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type cdylib [..]
228+
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
229+
",
230+
)
231+
.run();
232+
}
233+
234+
#[cargo_test]
235+
fn build_with_crate_type_for_foo_with_deps() {
220236
let p = project()
221-
.file("src/main.rs", "fn main() {}")
222-
.file("src/lib.rs", r#" "#)
237+
.file(
238+
"src/lib.rs",
239+
r#"
240+
extern crate a;
241+
pub fn foo() { a::hello(); }
242+
"#,
243+
)
244+
.file(
245+
"Cargo.toml",
246+
r#"
247+
[package]
248+
name = "foo"
249+
version = "0.0.1"
250+
authors = []
251+
252+
[dependencies]
253+
a = { path = "a" }
254+
"#,
255+
)
256+
.file("a/Cargo.toml", &basic_manifest("a", "0.1.0"))
257+
.file("a/src/lib.rs", "pub fn hello() {}")
223258
.build();
224259

225-
p.cargo("rustc -v --lib --crate-type lib -Zunstable-options")
260+
p.cargo("rustc -v --crate-type cdylib -Zunstable-options")
226261
.masquerade_as_nightly_cargo()
227262
.with_stderr(
228263
"\
264+
[COMPILING] a v0.1.0 ([CWD]/a)
265+
[RUNNING] `rustc --crate-name a a/src/lib.rs [..]--crate-type lib [..]
229266
[COMPILING] foo v0.0.1 ([CWD])
230-
[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type lib [..]
267+
[RUNNING] `rustc --crate-name foo src/lib.rs [..]--crate-type cdylib [..]
231268
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
232269
",
233270
)
@@ -236,12 +273,9 @@ fn build_with_crate_type_for_foo() {
236273

237274
#[cargo_test]
238275
fn build_with_crate_types_for_foo() {
239-
let p = project()
240-
.file("src/main.rs", "fn main() {}")
241-
.file("src/lib.rs", r#" "#)
242-
.build();
276+
let p = project().file("src/lib.rs", "").build();
243277

244-
p.cargo("rustc -v --lib --crate-type lib,cdylib -Zunstable-options")
278+
p.cargo("rustc -v --crate-type lib,cdylib -Zunstable-options")
245279
.masquerade_as_nightly_cargo()
246280
.with_stderr(
247281
"\

0 commit comments

Comments
 (0)