Skip to content

Commit 5e11afc

Browse files
committed
Expose build.target .cargo/config setting as packages.target in Cargo.toml
1 parent 0ed318d commit 5e11afc

File tree

19 files changed

+404
-36
lines changed

19 files changed

+404
-36
lines changed

crates/cargo-test-support/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ authors = ["Alex Crichton <[email protected]>"]
55
license = "MIT OR Apache-2.0"
66
edition = "2018"
77

8+
build = "build.rs"
9+
810
[lib]
911
doctest = false
1012

crates/cargo-test-support/build.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn main() {
2+
println!(
3+
"cargo:rustc-env=NATIVE_ARCH={}",
4+
std::env::var("TARGET").unwrap()
5+
);
6+
}

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,23 @@ rustup does not appear to be installed. Make sure that the appropriate
179179
panic!("{}", message);
180180
}
181181

182+
/// The arch triple of the test-running host.
183+
pub fn native() -> &'static str {
184+
env!("NATIVE_ARCH")
185+
}
186+
187+
pub fn native_arch() -> &'static str {
188+
match native()
189+
.split("-")
190+
.next()
191+
.expect("Target triple has unexpected format")
192+
{
193+
"x86_64" => "x86_64",
194+
"i686" => "x86",
195+
_ => panic!("This test should be gated on cross_compile::disabled."),
196+
}
197+
}
198+
182199
/// The alternate target-triple to build with.
183200
///
184201
/// Only use this function on tests that check `cross_compile::disabled`.
@@ -204,6 +221,15 @@ pub fn alternate_arch() -> &'static str {
204221
}
205222
}
206223

224+
/// A target-triple that is neither the host nor the target.
225+
///
226+
/// Rustc may not work with it and it's alright, apart from being a
227+
/// valid target triple it is supposed to be used only as a
228+
/// placeholder for targets that should not be considered.
229+
pub fn unused() -> &'static str {
230+
"wasm32-unknown-unknown"
231+
}
232+
207233
/// Whether or not the host can run cross-compiled executables.
208234
pub fn can_run_on_host() -> bool {
209235
if disabled() {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub struct BuildContext<'a, 'cfg> {
3939
pub packages: PackageSet<'cfg>,
4040

4141
/// Information about rustc and the target platform.
42-
pub target_data: RustcTargetData,
42+
pub target_data: RustcTargetData<'cfg>,
4343

4444
/// The root units of `unit_graph` (units requested on the command-line).
4545
pub roots: Vec<Unit>,
@@ -58,7 +58,7 @@ impl<'a, 'cfg> BuildContext<'a, 'cfg> {
5858
build_config: &'a BuildConfig,
5959
profiles: Profiles,
6060
extra_compiler_args: HashMap<Unit, Vec<String>>,
61-
target_data: RustcTargetData,
61+
target_data: RustcTargetData<'cfg>,
6262
roots: Vec<Unit>,
6363
unit_graph: UnitGraph,
6464
) -> CargoResult<BuildContext<'a, 'cfg>> {

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

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -655,9 +655,14 @@ fn env_args(
655655
}
656656

657657
/// Collection of information about `rustc` and the host and target.
658-
pub struct RustcTargetData {
658+
pub struct RustcTargetData<'cfg> {
659659
/// Information about `rustc` itself.
660660
pub rustc: Rustc,
661+
662+
/// Config
663+
config: &'cfg Config,
664+
requested_kinds: Vec<CompileKind>,
665+
661666
/// Build information for the "host", which is information about when
662667
/// `rustc` is invoked without a `--target` flag. This is used for
663668
/// procedural macros, build scripts, etc.
@@ -670,27 +675,17 @@ pub struct RustcTargetData {
670675
target_info: HashMap<CompileTarget, TargetInfo>,
671676
}
672677

673-
impl RustcTargetData {
678+
impl<'cfg> RustcTargetData<'cfg> {
674679
pub fn new(
675-
ws: &Workspace<'_>,
680+
ws: &Workspace<'cfg>,
676681
requested_kinds: &[CompileKind],
677-
) -> CargoResult<RustcTargetData> {
682+
) -> CargoResult<RustcTargetData<'cfg>> {
678683
let config = ws.config();
679684
let rustc = config.load_global_rustc(Some(ws))?;
680685
let host_config = config.target_cfg_triple(&rustc.host)?;
681686
let host_info = TargetInfo::new(config, requested_kinds, &rustc, CompileKind::Host)?;
682687
let mut target_config = HashMap::new();
683688
let mut target_info = HashMap::new();
684-
for kind in requested_kinds {
685-
if let CompileKind::Target(target) = *kind {
686-
let tcfg = config.target_cfg_triple(target.short_name())?;
687-
target_config.insert(target, tcfg);
688-
target_info.insert(
689-
target,
690-
TargetInfo::new(config, requested_kinds, &rustc, *kind)?,
691-
);
692-
}
693-
}
694689

695690
// This is a hack. The unit_dependency graph builder "pretends" that
696691
// `CompileKind::Host` is `CompileKind::Target(host)` if the
@@ -703,13 +698,56 @@ impl RustcTargetData {
703698
target_config.insert(ct, host_config.clone());
704699
}
705700

706-
Ok(RustcTargetData {
701+
let mut res = RustcTargetData {
707702
rustc,
703+
config,
704+
requested_kinds: requested_kinds.into(),
708705
host_config,
709706
host_info,
710707
target_config,
711708
target_info,
712-
})
709+
};
710+
711+
// Get all kinds we currently know about.
712+
//
713+
// For now, targets can only ever come from the root workspace
714+
// units as artifact dependencies are not a thing yet, so this
715+
// correctly represents all the kinds that can happen. When we
716+
// have artifact dependencies or other ways for targets to
717+
// appear at places that are not the root units, we may have
718+
// to revisit this.
719+
let all_kinds = requested_kinds
720+
.iter()
721+
.copied()
722+
.chain(ws.members().flat_map(|p| {
723+
p.manifest()
724+
.default_kind()
725+
.into_iter()
726+
.chain(p.manifest().forced_kind())
727+
}));
728+
for kind in all_kinds {
729+
if let CompileKind::Target(target) = kind {
730+
match res.target_config.entry(target) {
731+
std::collections::hash_map::Entry::Occupied(_) => (),
732+
std::collections::hash_map::Entry::Vacant(place) => {
733+
place.insert(res.config.target_cfg_triple(target.short_name())?);
734+
}
735+
}
736+
match res.target_info.entry(target) {
737+
std::collections::hash_map::Entry::Occupied(_) => (),
738+
std::collections::hash_map::Entry::Vacant(place) => {
739+
place.insert(TargetInfo::new(
740+
res.config,
741+
&res.requested_kinds,
742+
&res.rustc,
743+
kind,
744+
)?);
745+
}
746+
}
747+
}
748+
}
749+
750+
Ok(res)
713751
}
714752

715753
/// Returns a "short" name for the given kind, suitable for keying off

src/cargo/core/compiler/compilation.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,10 @@ impl<'cfg> Compilation<'cfg> {
127127
sysroot_target_libdir: bcx
128128
.all_kinds
129129
.iter()
130-
.map(|kind| {
130+
.map(|&kind| {
131131
(
132-
*kind,
133-
bcx.target_data.info(*kind).sysroot_target_libdir.clone(),
132+
kind,
133+
bcx.target_data.info(kind).sysroot_target_libdir.clone(),
134134
)
135135
})
136136
.collect(),

src/cargo/core/compiler/standard_lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub fn parse_unstable_flag(value: Option<&str>) -> Vec<String> {
3333
/// Resolve the standard library dependencies.
3434
pub fn resolve_std<'cfg>(
3535
ws: &Workspace<'cfg>,
36-
target_data: &RustcTargetData,
36+
target_data: &RustcTargetData<'cfg>,
3737
requested_targets: &[CompileKind],
3838
crates: &[String],
3939
) -> CargoResult<(PackageSet<'cfg>, Resolve, ResolvedFeatures)> {
@@ -185,7 +185,7 @@ pub fn generate_std_roots(
185185
Ok(ret)
186186
}
187187

188-
fn detect_sysroot_src_path(target_data: &RustcTargetData) -> CargoResult<PathBuf> {
188+
fn detect_sysroot_src_path(target_data: &RustcTargetData<'_>) -> CargoResult<PathBuf> {
189189
if let Some(s) = env::var_os("__CARGO_TESTS_ONLY_SRC_ROOT") {
190190
return Ok(s.into());
191191
}

src/cargo/core/compiler/unit_dependencies.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct State<'a, 'cfg> {
4444
/// library.
4545
is_std: bool,
4646
global_mode: CompileMode,
47-
target_data: &'a RustcTargetData,
47+
target_data: &'a RustcTargetData<'cfg>,
4848
profiles: &'a Profiles,
4949
interner: &'a UnitInterner,
5050

@@ -63,7 +63,7 @@ pub fn build_unit_dependencies<'a, 'cfg>(
6363
roots: &[Unit],
6464
std_roots: &HashMap<CompileKind, Vec<Unit>>,
6565
global_mode: CompileMode,
66-
target_data: &'a RustcTargetData,
66+
target_data: &'a RustcTargetData<'cfg>,
6767
profiles: &'a Profiles,
6868
interner: &'a UnitInterner,
6969
) -> CargoResult<UnitGraph> {

src/cargo/core/features.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,9 @@ features! {
390390

391391
// Support for 2021 edition.
392392
(unstable, edition2021, "", "reference/unstable.html#edition-2021"),
393+
394+
// Allow to specify per-package targets (compile kinds)
395+
(unstable, per_package_target, "", "reference/unstable.html#per-package-target"),
393396
}
394397

395398
const PUBLISH_LOCKFILE_REMOVED: &str = "The publish-lockfile key in Cargo.toml \

src/cargo/core/manifest.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use serde::ser;
1111
use serde::Serialize;
1212
use url::Url;
1313

14-
use crate::core::compiler::CrateType;
14+
use crate::core::compiler::{CompileKind, CrateType};
1515
use crate::core::resolver::ResolveBehavior;
1616
use crate::core::{Dependency, PackageId, PackageIdSpec, SourceId, Summary};
1717
use crate::core::{Edition, Feature, Features, WorkspaceConfig};
@@ -32,6 +32,8 @@ pub enum EitherManifest {
3232
pub struct Manifest {
3333
summary: Summary,
3434
targets: Vec<Target>,
35+
default_kind: Option<CompileKind>,
36+
forced_kind: Option<CompileKind>,
3537
links: Option<String>,
3638
warnings: Warnings,
3739
exclude: Vec<String>,
@@ -366,6 +368,8 @@ compact_debug! {
366368
impl Manifest {
367369
pub fn new(
368370
summary: Summary,
371+
default_kind: Option<CompileKind>,
372+
forced_kind: Option<CompileKind>,
369373
targets: Vec<Target>,
370374
exclude: Vec<String>,
371375
include: Vec<String>,
@@ -388,6 +392,8 @@ impl Manifest {
388392
) -> Manifest {
389393
Manifest {
390394
summary,
395+
default_kind,
396+
forced_kind,
391397
targets,
392398
warnings: Warnings::new(),
393399
exclude,
@@ -414,6 +420,12 @@ impl Manifest {
414420
pub fn dependencies(&self) -> &[Dependency] {
415421
self.summary.dependencies()
416422
}
423+
pub fn default_kind(&self) -> Option<CompileKind> {
424+
self.default_kind
425+
}
426+
pub fn forced_kind(&self) -> Option<CompileKind> {
427+
self.forced_kind
428+
}
417429
pub fn exclude(&self) -> &[String] {
418430
&self.exclude
419431
}
@@ -503,6 +515,17 @@ impl Manifest {
503515
})?;
504516
}
505517

518+
if self.default_kind.is_some() || self.forced_kind.is_some() {
519+
self.unstable_features
520+
.require(Feature::per_package_target())
521+
.chain_err(|| {
522+
anyhow::format_err!(
523+
"the `package.default-kind` and `package.forced-kind` \
524+
manifest keys are unstable and may not work properly"
525+
)
526+
})?;
527+
}
528+
506529
Ok(())
507530
}
508531

0 commit comments

Comments
 (0)