Skip to content

Commit 593a02f

Browse files
committed
Refactor Kind to carry target name in Target
This commit is an internal refactoring of Cargo's compilation backend to eventually support compiling multiple target simultaneously. The original motivation for this came up in discussion of #7297 and this has long been something I've intended to update Cargo for. Nothing in the backend currently exposes the ability to actually build multiple target simultaneously, but this should have no function change with respect to all current consumers. Eventually we'll need to refactor APIs of how you enter the compilation backend to compile for multiple targets.
1 parent 494cbd8 commit 593a02f

19 files changed

+203
-199
lines changed

crates/cargo-test-support/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1680,7 +1680,7 @@ pub static RUSTC: Rustc = Rustc::new(
16801680

16811681
/// The rustc host such as `x86_64-unknown-linux-gnu`.
16821682
pub fn rustc_host() -> String {
1683-
RUSTC.with(|r| r.host.clone())
1683+
RUSTC.with(|r| r.host.to_string())
16841684
}
16851685

16861686
pub fn is_nightly() -> bool {

src/cargo/core/compiler/build_config.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::path::Path;
33

44
use serde::ser;
55

6+
use crate::core::InternedString;
67
use crate::util::ProcessBuilder;
78
use crate::util::{CargoResult, CargoResultExt, Config, RustfixDiagnosticServer};
89

@@ -11,7 +12,7 @@ use crate::util::{CargoResult, CargoResultExt, Config, RustfixDiagnosticServer};
1112
pub struct BuildConfig {
1213
/// The target arch triple.
1314
/// Default: host arch.
14-
pub requested_target: Option<String>,
15+
pub requested_target: Option<InternedString>,
1516
/// Number of rustc jobs to run in parallel.
1617
pub jobs: u32,
1718
/// `true` if we are building for release.
@@ -91,7 +92,7 @@ impl BuildConfig {
9192
let jobs = jobs.or(cfg_jobs).unwrap_or(::num_cpus::get() as u32);
9293

9394
Ok(BuildConfig {
94-
requested_target: target,
95+
requested_target: target.as_ref().map(|s| s.into()),
9596
jobs,
9697
release: false,
9798
mode,

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

Lines changed: 36 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
use std::collections::HashMap;
2-
use std::path::{Path, PathBuf};
3-
use std::str;
4-
5-
use cargo_platform::Cfg;
6-
use log::debug;
7-
81
use crate::core::compiler::unit::UnitInterner;
92
use crate::core::compiler::{BuildConfig, BuildOutput, Kind, Unit};
103
use crate::core::profiles::Profiles;
11-
use crate::core::{Dependency, Workspace};
4+
use crate::core::{Dependency, InternedString, Workspace};
125
use crate::core::{PackageId, PackageSet};
136
use crate::util::errors::CargoResult;
14-
use crate::util::{profile, Config, Rustc};
7+
use crate::util::{Config, Rustc};
8+
use cargo_platform::Cfg;
9+
use std::collections::HashMap;
10+
use std::path::{Path, PathBuf};
11+
use std::str;
1512

1613
mod target_info;
1714
pub use self::target_info::{FileFlavor, TargetInfo};
@@ -36,11 +33,11 @@ pub struct BuildContext<'a, 'cfg> {
3633
/// Information about the compiler.
3734
pub rustc: Rustc,
3835
/// Build information for the host arch.
39-
pub host_config: TargetConfig,
36+
host_config: TargetConfig,
4037
/// Build information for the target.
41-
pub target_config: TargetConfig,
42-
pub target_info: TargetInfo,
43-
pub host_info: TargetInfo,
38+
target_config: HashMap<InternedString, TargetConfig>,
39+
target_info: HashMap<InternedString, TargetInfo>,
40+
host_info: TargetInfo,
4441
pub units: &'a UnitInterner<'a>,
4542
}
4643

@@ -57,19 +54,16 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
5754
let rustc = config.load_global_rustc(Some(ws))?;
5855

5956
let host_config = TargetConfig::new(config, &rustc.host)?;
60-
let target_config = match build_config.requested_target.as_ref() {
61-
Some(triple) => TargetConfig::new(config, triple)?,
62-
None => host_config.clone(),
63-
};
64-
let (host_info, target_info) = {
65-
let _p = profile::start("BuildContext::probe_target_info");
66-
debug!("probe_target_info");
67-
let host_info =
68-
TargetInfo::new(config, &build_config.requested_target, &rustc, Kind::Host)?;
69-
let target_info =
70-
TargetInfo::new(config, &build_config.requested_target, &rustc, Kind::Target)?;
71-
(host_info, target_info)
72-
};
57+
let host_info = TargetInfo::new(config, build_config.requested_target, &rustc, Kind::Host)?;
58+
let mut target_config = HashMap::new();
59+
let mut target_info = HashMap::new();
60+
if let Some(target) = build_config.requested_target {
61+
target_config.insert(target, TargetConfig::new(config, &target)?);
62+
target_info.insert(
63+
target,
64+
TargetInfo::new(config, Some(target), &rustc, Kind::Target(target))?,
65+
);
66+
}
7367

7468
Ok(BuildContext {
7569
ws,
@@ -96,11 +90,8 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
9690
Some(p) => p,
9791
None => return true,
9892
};
99-
let (name, info) = match kind {
100-
Kind::Host => (self.host_triple(), &self.host_info),
101-
Kind::Target => (self.target_triple(), &self.target_info),
102-
};
103-
platform.matches(name, info.cfg())
93+
let name = self.target_triple(kind);
94+
platform.matches(&name, self.cfg(kind))
10495
}
10596

10697
/// Gets the user-specified linker for a particular host or target.
@@ -115,11 +106,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
115106

116107
/// Gets the list of `cfg`s printed out from the compiler for the specified kind.
117108
pub fn cfg(&self, kind: Kind) -> &[Cfg] {
118-
let info = match kind {
119-
Kind::Host => &self.host_info,
120-
Kind::Target => &self.target_info,
121-
};
122-
info.cfg()
109+
self.info(kind).cfg()
123110
}
124111

125112
/// Gets the host architecture triple.
@@ -128,23 +115,23 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
128115
/// - machine: x86_64,
129116
/// - hardware-platform: unknown,
130117
/// - operating system: linux-gnu.
131-
pub fn host_triple(&self) -> &str {
132-
&self.rustc.host
118+
pub fn host_triple(&self) -> InternedString {
119+
self.rustc.host
133120
}
134121

135-
pub fn target_triple(&self) -> &str {
136-
self.build_config
137-
.requested_target
138-
.as_ref()
139-
.map(|s| s.as_str())
140-
.unwrap_or_else(|| self.host_triple())
122+
/// Returns the target triple associated with a `Kind`
123+
pub fn target_triple(&self, kind: Kind) -> InternedString {
124+
match kind {
125+
Kind::Host => self.host_triple(),
126+
Kind::Target(name) => name,
127+
}
141128
}
142129

143130
/// Gets the target configuration for a particular host or target.
144-
fn target_config(&self, kind: Kind) -> &TargetConfig {
131+
pub fn target_config(&self, kind: Kind) -> &TargetConfig {
145132
match kind {
146133
Kind::Host => &self.host_config,
147-
Kind::Target => &self.target_config,
134+
Kind::Target(s) => &self.target_config[&s],
148135
}
149136
}
150137

@@ -165,10 +152,10 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
165152
pkg.source_id().is_path() || self.config.extra_verbose()
166153
}
167154

168-
fn info(&self, kind: Kind) -> &TargetInfo {
155+
pub fn info(&self, kind: Kind) -> &TargetInfo {
169156
match kind {
170157
Kind::Host => &self.host_info,
171-
Kind::Target => &self.target_info,
158+
Kind::Target(s) => &self.target_info[&s],
172159
}
173160
}
174161

@@ -181,10 +168,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
181168
/// `lib_name` is the `links` library name and `kind` is whether it is for
182169
/// Host or Target.
183170
pub fn script_override(&self, lib_name: &str, kind: Kind) -> Option<&BuildOutput> {
184-
match kind {
185-
Kind::Host => self.host_config.overrides.get(lib_name),
186-
Kind::Target => self.target_config.overrides.get(lib_name),
187-
}
171+
self.target_config(kind).overrides.get(lib_name)
188172
}
189173
}
190174

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

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::path::PathBuf;
55
use std::str::{self, FromStr};
66

77
use crate::core::compiler::Kind;
8+
use crate::core::InternedString;
89
use crate::core::TargetKind;
910
use crate::util::{CargoResult, CargoResultExt, Config, ProcessBuilder, Rustc};
1011
use cargo_platform::{Cfg, CfgExpr};
@@ -80,7 +81,7 @@ impl FileType {
8081
impl TargetInfo {
8182
pub fn new(
8283
config: &Config,
83-
requested_target: &Option<String>,
84+
requested_target: Option<InternedString>,
8485
rustc: &Rustc,
8586
kind: Kind,
8687
) -> CargoResult<TargetInfo> {
@@ -101,12 +102,8 @@ impl TargetInfo {
101102
.args(&rustflags)
102103
.env_remove("RUSTC_LOG");
103104

104-
let target_triple = requested_target
105-
.as_ref()
106-
.map(|s| s.as_str())
107-
.unwrap_or(&rustc.host);
108-
if kind == Kind::Target {
109-
process.arg("--target").arg(target_triple);
105+
if let Kind::Target(target) = kind {
106+
process.arg("--target").arg(target);
110107
}
111108

112109
let crate_type_process = process.clone();
@@ -148,10 +145,10 @@ impl TargetInfo {
148145
}
149146
rustlib
150147
}
151-
Kind::Target => {
148+
Kind::Target(target) => {
152149
rustlib.push("lib");
153150
rustlib.push("rustlib");
154-
rustlib.push(target_triple);
151+
rustlib.push(target);
155152
rustlib.push("lib");
156153
rustlib
157154
}
@@ -381,7 +378,7 @@ fn output_err_info(cmd: &ProcessBuilder, stdout: &str, stderr: &str) -> String {
381378
/// scripts, ...), even if it is the same as the target.
382379
fn env_args(
383380
config: &Config,
384-
requested_target: &Option<String>,
381+
requested_target: Option<InternedString>,
385382
host_triple: &str,
386383
target_cfg: Option<&[Cfg]>,
387384
kind: Kind,
@@ -407,9 +404,7 @@ fn env_args(
407404
// same as the host, build scripts in plugins won't get
408405
// RUSTFLAGS.
409406
let compiling_with_target = requested_target.is_some();
410-
let is_target_kind = kind == Kind::Target;
411-
412-
if compiling_with_target && !is_target_kind {
407+
if compiling_with_target && kind.is_host() {
413408
// This is probably a build script or plugin and we're
414409
// compiling with --target. In this scenario there are
415410
// no rustflags we can apply.

src/cargo/core/compiler/compilation.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use cargo_platform::CfgExpr;
77
use semver::Version;
88

99
use super::BuildContext;
10+
use crate::core::compiler::Kind;
1011
use crate::core::{Edition, InternedString, Package, PackageId, Target};
1112
use crate::util::{self, join_paths, process, rustc::Rustc, CargoResult, Config, ProcessBuilder};
1213

@@ -78,7 +79,10 @@ pub struct Compilation<'cfg> {
7879
}
7980

8081
impl<'cfg> Compilation<'cfg> {
81-
pub fn new<'a>(bcx: &BuildContext<'a, 'cfg>) -> CargoResult<Compilation<'cfg>> {
82+
pub fn new<'a>(
83+
bcx: &BuildContext<'a, 'cfg>,
84+
default_kind: Kind,
85+
) -> CargoResult<Compilation<'cfg>> {
8286
let mut rustc = bcx.rustc.process();
8387

8488
let mut primary_unit_rustc_process = bcx.build_config.primary_unit_rustc.clone();
@@ -97,8 +101,8 @@ impl<'cfg> Compilation<'cfg> {
97101
root_output: PathBuf::from("/"),
98102
deps_output: PathBuf::from("/"),
99103
host_deps_output: PathBuf::from("/"),
100-
host_dylib_path: bcx.host_info.sysroot_libdir.clone(),
101-
target_dylib_path: bcx.target_info.sysroot_libdir.clone(),
104+
host_dylib_path: bcx.info(Kind::Host).sysroot_libdir.clone(),
105+
target_dylib_path: bcx.info(default_kind).sysroot_libdir.clone(),
102106
tests: Vec::new(),
103107
binaries: Vec::new(),
104108
extra_env: HashMap::new(),
@@ -109,8 +113,8 @@ impl<'cfg> Compilation<'cfg> {
109113
rustc_process: rustc,
110114
primary_unit_rustc_process,
111115
host: bcx.host_triple().to_string(),
112-
target: bcx.target_triple().to_string(),
113-
target_runner: target_runner(bcx)?,
116+
target: bcx.target_triple(default_kind).to_string(),
117+
target_runner: target_runner(bcx, default_kind)?,
114118
supports_rustdoc_crate_type: supports_rustdoc_crate_type(bcx.config, &bcx.rustc)?,
115119
})
116120
}
@@ -289,8 +293,11 @@ fn pre_version_component(v: &Version) -> String {
289293
ret
290294
}
291295

292-
fn target_runner(bcx: &BuildContext<'_, '_>) -> CargoResult<Option<(PathBuf, Vec<String>)>> {
293-
let target = bcx.target_triple();
296+
fn target_runner(
297+
bcx: &BuildContext<'_, '_>,
298+
kind: Kind,
299+
) -> CargoResult<Option<(PathBuf, Vec<String>)>> {
300+
let target = bcx.target_triple(kind);
294301

295302
// try target.{}.runner
296303
let key = format!("target.{}.runner", target);
@@ -303,7 +310,7 @@ fn target_runner(bcx: &BuildContext<'_, '_>) -> CargoResult<Option<(PathBuf, Vec
303310
let mut matching_runner = None;
304311

305312
for key in table.val.keys() {
306-
if CfgExpr::matches_key(key, bcx.target_info.cfg()) {
313+
if CfgExpr::matches_key(key, bcx.info(kind).cfg()) {
307314
let key = format!("target.{}.runner", key);
308315
if let Some(runner) = bcx.config.get_path_and_args(&key)? {
309316
// more than one match, error out

0 commit comments

Comments
 (0)