Skip to content

Commit b833643

Browse files
committed
Override target crate-type for cargo rustc --crate-type
Instead of writing override rules all over the compilation logic, this commit simply override the unit created by `generate_targets`. As a result, `cargo rustc --crate-type` behaves exactly as expected.
1 parent 497051a commit b833643

File tree

3 files changed

+55
-45
lines changed

3 files changed

+55
-45
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+
}

0 commit comments

Comments
 (0)