Skip to content

Commit

Permalink
Refactor that prepares to add rustc sysroot to BuildPlatforms
Browse files Browse the repository at this point in the history
* Create a serialized form of `BuildPlatforms`: `BuildPlatformsSummary`
* Change `discover_build_platforms` to `discover_target_triple` which only discovers the `TargetTriple`
  • Loading branch information
06393993 committed May 14, 2024
1 parent 3a8ae64 commit 627e282
Show file tree
Hide file tree
Showing 6 changed files with 256 additions and 32 deletions.
18 changes: 10 additions & 8 deletions cargo-nextest/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use nextest_runner::{
VersionOnlyConfig,
},
double_spawn::DoubleSpawnInfo,
errors::{UnknownHostPlatform, WriteTestListError},
errors::WriteTestListError,
list::{
BinaryList, OutputFormat, RustTestArtifact, SerializableFormat, TestExecuteContext,
TestList,
Expand Down Expand Up @@ -1006,7 +1006,11 @@ impl BaseApp {
// Next, read the build platforms.
let build_platforms = match reuse_build.binaries_metadata() {
Some(kind) => kind.binary_list.rust_build_meta.build_platforms.clone(),
None => discover_build_platforms(&cargo_configs, cargo_opts.target.as_deref())?,
None => {
let target_triple =
discover_target_triple(&cargo_configs, cargo_opts.target.as_deref());
BuildPlatforms::new(target_triple)?
}
};

// Read the Cargo metadata.
Expand Down Expand Up @@ -1927,11 +1931,11 @@ fn acquire_graph_data(
Ok(json)
}

fn discover_build_platforms(
fn discover_target_triple(
cargo_configs: &CargoConfigs,
target_cli_option: Option<&str>,
) -> Result<BuildPlatforms, UnknownHostPlatform> {
let target_triple = match TargetTriple::find(cargo_configs, target_cli_option) {
) -> Option<TargetTriple> {
match TargetTriple::find(cargo_configs, target_cli_option) {
Ok(Some(triple)) => {
log::debug!(
"using target triple `{}` defined by `{}`; {}",
Expand All @@ -1950,9 +1954,7 @@ fn discover_build_platforms(
warn_on_err("target triple", &err);
None
}
};

BuildPlatforms::new(target_triple)
}
}

fn runner_for_target(
Expand Down
20 changes: 19 additions & 1 deletion nextest-metadata/src/test_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ pub enum RustBinaryIdNameAndKind<'a> {
}

/// Rust metadata used for builds and test runs.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize, Default)]
#[serde(rename_all = "kebab-case")]
pub struct RustBuildMetaSummary {
/// The target directory for Rust artifacts.
Expand All @@ -485,6 +485,11 @@ pub struct RustBuildMetaSummary {

/// The target platforms used while compiling the Rust artifacts.
#[serde(default)]
pub target_platforms_v2: Vec<BuildPlatformsSummary>,

/// Deprecated in favor of target_platforms_v2. The target platforms used while compiling the
/// Rust artifacts.
#[serde(default)]
pub target_platforms: Vec<PlatformSummary>,

/// A deprecated form of the target platform used for cross-compilation, if any.
Expand All @@ -510,6 +515,17 @@ pub struct RustNonTestBinarySummary {
pub path: Utf8PathBuf,
}

/// Serialized representation of host and target platforms.
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub struct BuildPlatformsSummary {
/// The target platform, if specified.
///
/// In the future, this will become a list of target triples once multiple `--target` arguments
/// are supported.
pub target: PlatformSummary,
}

/// Information about the kind of a Rust non-test binary.
///
/// This is part of [`RustNonTestBinarySummary`], and is used to determine runtime environment
Expand Down Expand Up @@ -705,6 +721,7 @@ mod tests {
linked_paths: BTreeSet::new(),
target_platform: None,
target_platforms: vec![],
target_platforms_v2: vec![],
}; "no target platform")]
#[test_case(r#"{
"target-directory": "/foo",
Expand All @@ -720,6 +737,7 @@ mod tests {
linked_paths: BTreeSet::new(),
target_platform: Some("x86_64-unknown-linux-gnu".to_owned()),
target_platforms: vec![],
target_platforms_v2: vec![],
}; "single target platform specified")]
fn test_deserialize_old_rust_build_meta(input: &str, expected: RustBuildMetaSummary) {
let build_meta: RustBuildMetaSummary =
Expand Down
8 changes: 8 additions & 0 deletions nextest-runner/src/list/binary_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,14 @@ mod tests {
},
"build-script-out-dirs": {},
"linked-paths": [],
"target-platforms-v2": [
{
"target": {
"triple": "x86_64-unknown-linux-gnu",
"target-features": "unknown"
}
}
],
"target-platforms": [
{
"triple": "x86_64-unknown-linux-gnu",
Expand Down
156 changes: 143 additions & 13 deletions nextest-runner/src/list/rust_build_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

use crate::{
cargo_config::TargetTriple,
errors::RustBuildMetaParseError,
helpers::convert_rel_path_to_main_sep,
list::{BinaryListState, TestListState},
Expand Down Expand Up @@ -135,15 +134,15 @@ impl RustBuildMeta<TestListState> {
impl<State> RustBuildMeta<State> {
/// Creates a `RustBuildMeta` from a serializable summary.
pub fn from_summary(summary: RustBuildMetaSummary) -> Result<Self, RustBuildMetaParseError> {
let target_triple = if !summary.target_platforms.is_empty() {
// TODO: support multiple --target options
TargetTriple::deserialize(summary.target_platforms.first().cloned())?
let build_platforms = if let Some(summary) = summary.target_platforms_v2.first() {
summary.clone().try_into()?
} else if let Some(summary) = summary.target_platforms.first() {
// Compatibility with metadata generated by older versions of nextest.
summary.clone().try_into()?
} else {
// Compatibility with metadata generated by older versions of nextest.
TargetTriple::deserialize_str(summary.target_platform)?
BuildPlatforms::from_summary_str(summary.target_platform.clone())?
};
let build_platforms = BuildPlatforms::new(target_triple)
.map_err(|error| RustBuildMetaParseError::UnknownHostPlatform(error.error))?;

Ok(Self {
target_directory: summary.target_directory,
Expand All @@ -168,13 +167,144 @@ impl<State> RustBuildMeta<State> {
non_test_binaries: self.non_test_binaries.clone(),
build_script_out_dirs: self.build_script_out_dirs.clone(),
linked_paths: self.linked_paths.keys().cloned().collect(),
target_platform: self
.build_platforms
.target
.as_ref()
.map(|triple| triple.platform.triple_str().to_owned()),
target_platform: self.build_platforms.to_summary_str(),
target_platforms: vec![self.build_platforms.clone().into()],
// TODO: support multiple --target options
target_platforms: vec![self.build_platforms.to_summary()],
target_platforms_v2: vec![self.build_platforms.clone().into()],
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::cargo_config::TargetTriple;
use nextest_metadata::BuildPlatformsSummary;
use target_spec::{summaries::PlatformSummary, Platform};
use test_case::test_case;

impl Default for RustBuildMeta<BinaryListState> {
fn default() -> Self {
RustBuildMeta::<BinaryListState>::new(
Utf8PathBuf::default(),
BuildPlatforms::new(None)
.expect("creating BuildPlatforms without target triple should succeed"),
)
}
}

fn x86_64_unknown_linux_gnu_triple() -> TargetTriple {
TargetTriple::deserialize_str(Some("x86_64-unknown-linux-gnu".to_owned()))
.expect("creating TargetTriple from linux gnu triple string shoould succeed")
.expect("the output of deserialize_str shouldn't be None")
}

fn x86_64_pc_windows_msvc_triple() -> TargetTriple {
TargetTriple::deserialize_str(Some("x86_64-pc-windows-msvc".to_owned()))
.expect("creating TargetTriple from windows msvc triple string shoould succeed")
.expect("the output of deserialize_str shouldn't be None")
}

fn x86_64_apple_darwin_triple() -> TargetTriple {
TargetTriple::deserialize_str(Some("x86_64-apple-darwin".to_owned()))
.expect("creating TargetTriple from apple triple string shoould succeed")
.expect("the output of deserialize_str shouldn't be None")
}

fn host_platform() -> Platform {
Platform::current().expect("should detect the host platform successfully")
}

#[test_case(RustBuildMetaSummary {
..Default::default()
}, RustBuildMeta::<BinaryListState> {
build_platforms: BuildPlatforms {
host: host_platform(),
target: None,
},
..Default::default()
}; "no target platforms")]
#[test_case(RustBuildMetaSummary {
target_platform: Some("x86_64-unknown-linux-gnu".to_owned()),
..Default::default()
}, RustBuildMeta::<BinaryListState> {
build_platforms: BuildPlatforms {
host: host_platform(),
target: Some(x86_64_unknown_linux_gnu_triple()),
},
..Default::default()
}; "only target platform field")]
#[test_case(RustBuildMetaSummary {
target_platform: Some("x86_64-unknown-linux-gnu".to_owned()),
target_platforms: vec![PlatformSummary::new("x86_64-pc-windows-msvc")],
..Default::default()
}, RustBuildMeta::<BinaryListState> {
build_platforms: BuildPlatforms {
host: host_platform(),
target: Some(x86_64_pc_windows_msvc_triple()),
},
..Default::default()
}; "target platform and target platforms field")]
#[test_case(RustBuildMetaSummary {
target_platform: Some("x86_64-unknown-linux-gnu".to_owned()),
target_platforms: vec![PlatformSummary::new("x86_64-pc-windows-msvc")],
target_platforms_v2: vec![BuildPlatformsSummary {
target: PlatformSummary::new("x86_64-apple-darwin"),
}],
..Default::default()
}, RustBuildMeta::<BinaryListState> {
build_platforms: BuildPlatforms {
host: host_platform(),
target: Some(x86_64_apple_darwin_triple()),
},
..Default::default()
}; "target platform and target platforms and target platforms v2 field")]
fn test_from_summary(summary: RustBuildMetaSummary, expected: RustBuildMeta<BinaryListState>) {
let actual = RustBuildMeta::<BinaryListState>::from_summary(summary)
.expect("RustBuildMeta should deserialize from summary with success.");
assert_eq!(actual, expected);
}

fn not_host_platform_triple() -> TargetTriple {
cfg_if::cfg_if! {
if #[cfg(windows)] {
x86_64_unknown_linux_gnu_triple()
} else {
x86_64_pc_windows_msvc_triple()
}
}
}

#[test_case(RustBuildMeta::<BinaryListState> {
build_platforms: BuildPlatforms {
host: host_platform(),
target: None,
},
..Default::default()
}, RustBuildMetaSummary {
target_platform: None,
target_platforms: vec![host_platform().to_summary()],
target_platforms_v2: vec![BuildPlatformsSummary{
target: host_platform().to_summary()
}],
..Default::default()
}; "build platforms without target")]
#[test_case(RustBuildMeta::<BinaryListState> {
build_platforms: BuildPlatforms {
host: host_platform(),
target: Some(not_host_platform_triple()),
},
..Default::default()
}, RustBuildMetaSummary {
target_platform: Some(not_host_platform_triple().platform.triple_str().to_owned()),
target_platforms: vec![not_host_platform_triple().platform.to_summary()],
target_platforms_v2: vec![BuildPlatformsSummary{
target: not_host_platform_triple().platform.to_summary()
}],
..Default::default()
}; "build platforms with target")]
fn test_to_summary(meta: RustBuildMeta<BinaryListState>, expected: RustBuildMetaSummary) {
let actual = meta.to_summary();
assert_eq!(actual, expected);
}
}
8 changes: 8 additions & 0 deletions nextest-runner/src/list/test_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,14 @@ mod tests {
"non-test-binaries": {},
"build-script-out-dirs": {},
"linked-paths": [],
"target-platforms-v2": [
{
"target": {
"triple": "aarch64-unknown-linux-gnu",
"target-features": "unknown"
}
}
],
"target-platforms": [
{
"triple": "aarch64-unknown-linux-gnu",
Expand Down
Loading

0 comments on commit 627e282

Please sign in to comment.