From 2122f096536566e607e814873060280e3e05b893 Mon Sep 17 00:00:00 2001 From: Zac Mrowicki Date: Thu, 18 Mar 2021 20:41:27 +0000 Subject: [PATCH 1/2] buildsys: Add ability for variants to specify supported architectures This change adds an additional key that can be specified in a variant's `Cargo.toml`, `supported-arches`. It is a list and the supported enum values are `x86_64` and `aarch64`. If `supported-arches` is specified, the current `BUILDSYS_ARCH` is checked against the list. If `supported-arches` is not specified, the build continues as before. --- tools/buildsys/src/main.rs | 52 ++++++++++++++++++++++++++++++++-- tools/buildsys/src/manifest.rs | 25 ++++++++++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/tools/buildsys/src/main.rs b/tools/buildsys/src/main.rs index ac4f8578748..e6b3a18a59b 100644 --- a/tools/buildsys/src/main.rs +++ b/tools/buildsys/src/main.rs @@ -16,10 +16,10 @@ mod spec; use builder::{PackageBuilder, VariantBuilder}; use cache::LookasideCache; -use manifest::ManifestInfo; +use manifest::{ManifestInfo, SupportedArch}; use project::ProjectInfo; use serde::Deserialize; -use snafu::ResultExt; +use snafu::{ensure, ResultExt}; use spec::SpecInfo; use std::env; use std::path::PathBuf; @@ -56,6 +56,22 @@ mod error { var: String, source: std::env::VarError, }, + + #[snafu(display("Unknown architecture: '{}'", arch))] + UnknownArch { + arch: String, + source: serde_plain::Error, + }, + + #[snafu(display( + "Unsupported architecture {}, this variant supports {}", + arch, + supported_arches.join(", ") + ))] + UnsupportedArch { + arch: String, + supported_arches: Vec, + }, } } @@ -102,10 +118,17 @@ fn run() -> Result<()> { } fn build_package() -> Result<()> { - let manifest_dir: PathBuf = getenv("CARGO_MANIFEST_DIR")?.into(); let manifest_file = "Cargo.toml"; println!("cargo:rerun-if-changed={}", manifest_file); + let root_dir: PathBuf = getenv("BUILDSYS_ROOT_DIR")?.into(); + let variant = getenv("BUILDSYS_VARIANT")?; + let variant_manifest_path = root_dir.join("variants").join(variant).join(manifest_file); + let variant_manifest = + ManifestInfo::new(variant_manifest_path).context(error::ManifestParse)?; + supported_arch(&variant_manifest)?; + + let manifest_dir: PathBuf = getenv("CARGO_MANIFEST_DIR")?.into(); let manifest = ManifestInfo::new(manifest_dir.join(manifest_file)).context(error::ManifestParse)?; @@ -165,6 +188,8 @@ fn build_variant() -> Result<()> { let manifest = ManifestInfo::new(manifest_dir.join(manifest_file)).context(error::ManifestParse)?; + supported_arch(&manifest)?; + if let Some(packages) = manifest.included_packages() { let image_format = manifest.image_format(); VariantBuilder::build(&packages, image_format).context(error::BuildAttempt)?; @@ -175,6 +200,27 @@ fn build_variant() -> Result<()> { Ok(()) } +/// Ensure that the current arch is supported by the current variant +fn supported_arch(manifest: &ManifestInfo) -> Result<()> { + if let Some(supported_arches) = manifest.supported_arches() { + let arch = getenv("BUILDSYS_ARCH")?; + let current_arch: SupportedArch = + serde_plain::from_str(&arch).context(error::UnknownArch { arch: &arch })?; + + ensure!( + supported_arches.contains(¤t_arch), + error::UnsupportedArch { + arch: &arch, + supported_arches: supported_arches + .into_iter() + .map(|a| a.to_string()) + .collect::>() + } + ) + } + Ok(()) +} + /// Retrieve a variable that we expect to be set in the environment. fn getenv(var: &str) -> Result { env::var(var).context(error::Environment { var }) diff --git a/tools/buildsys/src/manifest.rs b/tools/buildsys/src/manifest.rs index a606048f44e..1d9381f6520 100644 --- a/tools/buildsys/src/manifest.rs +++ b/tools/buildsys/src/manifest.rs @@ -65,6 +65,8 @@ use error::Result; use serde::Deserialize; use snafu::ResultExt; +use std::collections::HashSet; +use std::fmt; use std::fs; use std::path::{Path, PathBuf}; @@ -115,6 +117,12 @@ impl ManifestInfo { self.build_variant().and_then(|b| b.image_format.as_ref()) } + /// Convenience method to return the supported architectures for this variant. + pub(crate) fn supported_arches(&self) -> Option<&HashSet> { + self.build_variant() + .and_then(|b| b.supported_arches.as_ref()) + } + /// Helper methods to navigate the series of optional struct fields. fn build_package(&self) -> Option<&BuildPackage> { self.package @@ -158,6 +166,7 @@ pub(crate) struct BuildPackage { pub(crate) struct BuildVariant { pub(crate) included_packages: Option>, pub(crate) image_format: Option, + pub(crate) supported_arches: Option>, } #[derive(Deserialize, Debug)] @@ -167,6 +176,13 @@ pub(crate) enum ImageFormat { Vmdk, } +#[derive(Deserialize, Debug, PartialEq, Eq, Hash)] +#[serde(rename_all = "lowercase")] +pub(crate) enum SupportedArch { + X86_64, + Aarch64, +} + #[derive(Deserialize, Debug)] #[serde(rename_all = "kebab-case")] pub(crate) struct ExternalFile { @@ -174,3 +190,12 @@ pub(crate) struct ExternalFile { pub(crate) sha512: String, pub(crate) url: String, } + +impl fmt::Display for SupportedArch { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + SupportedArch::X86_64 => write!(f, "x86_64"), + SupportedArch::Aarch64 => write!(f, "aarch64"), + } + } +} From 0b7080749b4b8b06c993ca3e798c63b6704e0c21 Mon Sep 17 00:00:00 2001 From: Zac Mrowicki Date: Tue, 30 Mar 2021 22:49:36 +0000 Subject: [PATCH 2/2] vmware-dev: Support x86_64 only This change adds the `supported-arch` key to `vmware-dev`'s `Cargo.toml` and ensure's the variant will only be built for `x86_64`. --- variants/vmware-dev/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/variants/vmware-dev/Cargo.toml b/variants/vmware-dev/Cargo.toml index 894fedc3f95..b651cfa4b9d 100644 --- a/variants/vmware-dev/Cargo.toml +++ b/variants/vmware-dev/Cargo.toml @@ -9,6 +9,7 @@ exclude = ["README.md"] [package.metadata.build-variant] image-format = "vmdk" +supported-arches = ["x86_64"] included-packages = [ # core "release",