diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bcc1f3a46..1905fc506 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -203,7 +203,7 @@ jobs: id: build-docker-image if: steps.prepare-meta.outputs.has-image timeout-minutes: 120 - run: cargo xtask build-docker-image -v "${TARGET}${SUB:+.$SUB}" ${{ matrix.verbose && '-v' || '' }} --platform ${{ matrix.platform }} + run: cargo xtask build-docker-image -v "${TARGET}${SUB:+.$SUB}" ${{ matrix.verbose && '-v' || '' }}${{ matrix.platform && '--platform ' }}${{ join(matrix.platform) || '' }} env: TARGET: ${{ matrix.target }} SUB: ${{ matrix.sub }} @@ -323,7 +323,7 @@ jobs: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || startsWith(github.ref, 'refs/tags/v') ) - run: cargo xtask build-docker-image -v --push "${TARGET}${SUB:+.$SUB}" --platform ${{ join(matrix.platforms, ',') }} + run: cargo xtask build-docker-image -v --push "${TARGET}${SUB:+.$SUB}" ${{ matrix.verbose && '-v' || '' }}${{ matrix.platform && '--platform ' }}${{ join(matrix.platform) || '' }} env: TARGET: ${{ matrix.target }} SUB: ${{ matrix.sub }} diff --git a/docker/qemu.sh b/docker/qemu.sh index 3a144ea3d..01a0b4e2e 100755 --- a/docker/qemu.sh +++ b/docker/qemu.sh @@ -131,7 +131,7 @@ build_static_slirp() { rm -rf "${td}" } - +# passed arg 1: $1 = arch, so for example "arm64" or "aarch64" main() { local version=5.1.0 diff --git a/src/docker/image.rs b/src/docker/image.rs index 6749fe86d..5a7331da2 100644 --- a/src/docker/image.rs +++ b/src/docker/image.rs @@ -162,7 +162,7 @@ impl From for ImageReference { /// The architecture/platform to use in the image /// /// -#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize)] #[serde(try_from = "String")] pub struct ImagePlatform { /// CPU architecture, x86_64, aarch64 etc diff --git a/src/docker/provided_images.rs b/src/docker/provided_images.rs index a7f2b0106..49ce586a1 100644 --- a/src/docker/provided_images.rs +++ b/src/docker/provided_images.rs @@ -5,7 +5,7 @@ use super::{ImagePlatform, ProvidedImage}; pub static PROVIDED_IMAGES: &[ProvidedImage] = &[ ProvidedImage { name: "x86_64-unknown-linux-gnu", - platforms: &[ImagePlatform::X86_64_UNKNOWN_LINUX_GNU], + platforms: &[ImagePlatform::X86_64_UNKNOWN_LINUX_GNU, ImagePlatform::AARCH64_UNKNOWN_LINUX_GNU], sub: None }, ProvidedImage { diff --git a/src/lib.rs b/src/lib.rs index a65668e17..171cb661b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -72,7 +72,7 @@ pub use self::rustc::{TargetList, VersionMetaExt}; pub const CROSS_LABEL_DOMAIN: &str = "org.cross-rs"; #[allow(non_camel_case_types)] -#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Hash, PartialOrd, Ord)] #[serde(from = "&str", into = "String")] #[serde(rename_all = "snake_case")] pub enum TargetTriple { diff --git a/targets.toml b/targets.toml index 609698573..ca85482aa 100644 --- a/targets.toml +++ b/targets.toml @@ -18,6 +18,7 @@ std = true run = true runners = "native qemu-user qemu-system" deploy = true +platforms = ["x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu"] [[target]] target = "x86_64-unknown-linux-musl" @@ -402,6 +403,7 @@ os = "ubuntu-latest" cpp = true std = true run = true +platforms = ["x86_64-unknown-linux-gnu"] [[target]] target = "i686-pc-windows-gnu" @@ -409,6 +411,7 @@ os = "ubuntu-latest" cpp = true std = true run = true +platforms = ["x86_64-unknown-linux-gnu"] [[target]] # Disabled for now, see https://github.com/rust-lang/rust/issues/98216 & https://github.com/cross-rs/cross/issues/634 @@ -545,3 +548,4 @@ dylib = true std = true run = true runners = "qemu-user qemu-system" +platforms = ["x86_64-unknown-linux-gnu"] diff --git a/xtask/src/build_docker_image.rs b/xtask/src/build_docker_image.rs index 374596980..7a6074872 100644 --- a/xtask/src/build_docker_image.rs +++ b/xtask/src/build_docker_image.rs @@ -146,6 +146,12 @@ pub fn build_docker_image( .contents_first(true) .into_iter() .filter_map(|e| e.ok().filter(|f| f.file_type().is_file())) + // don't add native + .filter(|f| { + !f.file_name() + .to_string_lossy() + .starts_with("Dockerfile.native") + }) .filter_map(|f| { f.file_name() .to_string_lossy() @@ -156,6 +162,17 @@ pub fn build_docker_image( .collect(); } } + + // grab platform from the targets.toml file, if it exists. + targets.iter_mut().for_each(|t| { + if let Some(m) = get_matrix() + .iter() + .find(|m| m.target == t.name && m.sub == t.sub) + { + t.platform = m.platforms.clone(); + } + }); + let gha = std::env::var("GITHUB_ACTIONS").is_ok(); let mut progress = progress.map(|x| x.parse().unwrap()); if gha { @@ -176,9 +193,19 @@ pub fn build_docker_image( }; let mut results = vec![]; - for (target, dockerfile) in targets.iter() { + for (platform, (target, dockerfile)) in targets + .iter() + .flat_map(|(t, d)| { + t.platform + .as_deref() + .unwrap_or(&platforms) + .iter() + .map(move |p| (p, (t, d))) + }) + .filter(|(p, _)| platforms.contains(p)) + { if gha && targets.len() > 1 { - gha_print("::group::Build {target}"); + gha_print(&format!("::group::Build {target} for {}", platform.target)); } else { msg_info.note(format_args!( "Build {target} for {}", diff --git a/xtask/src/ci/target_matrix.rs b/xtask/src/ci/target_matrix.rs index 19865ffe0..732441ee2 100644 --- a/xtask/src/ci/target_matrix.rs +++ b/xtask/src/ci/target_matrix.rs @@ -1,12 +1,12 @@ use std::process::Command; -use crate::util::{get_matrix, gha_output, gha_print, CiTarget, ImageTarget}; use clap::builder::{BoolishValueParser, PossibleValuesParser}; use clap::Parser; -use cross::docker::ImagePlatform; -use cross::{shell::Verbosity, CommandExt}; +use cross::{docker::ImagePlatform, shell::Verbosity, CommandExt}; use serde::{Deserialize, Serialize}; +use crate::util::{get_matrix, gha_output, gha_print, CiTarget, ImageTarget}; + #[derive(Parser, Debug)] pub struct TargetMatrix { /// check is being run as part of a weekly check @@ -64,6 +64,7 @@ impl TargetMatrix { runners: vec![], none: false, has_image: true, + platform: vec![], verbose: false, tests: vec!["all".to_owned()], }, @@ -341,6 +342,8 @@ struct TargetMatrixArgs { none: bool, #[clap(long)] has_image: bool, + #[clap(long, num_args = 0..)] + platform: Vec, #[clap(long, short)] verbose: bool, #[clap(long, value_parser = PossibleValuesParser::new(&[ @@ -370,6 +373,7 @@ impl Default for TargetMatrixArgs { runners: Vec::new(), none: false, has_image: false, + platform: Vec::new(), verbose: false, tests: vec!["all".to_owned()], } @@ -423,6 +427,22 @@ impl TargetMatrixArgs { .any(|runner| m.runners.as_deref().unwrap_or_default().contains(runner)) }); } + if !self.platform.is_empty() { + matrix.retain(|t| { + t.platforms() + .iter() + .any(|platform| self.platform.contains(platform)) + }); + matrix.iter_mut().for_each(|t| { + t.platforms = Some( + t.platforms() + .iter() + .filter(|&p| self.platform.contains(p)) + .cloned() + .collect(), + ) + }); + } } fn tests(&self) -> Result { diff --git a/xtask/src/util.rs b/xtask/src/util.rs index 899cffdd8..5d35fa261 100644 --- a/xtask/src/util.rs +++ b/xtask/src/util.rs @@ -4,10 +4,9 @@ use std::io::Write; use std::path::{Path, PathBuf}; use std::process::Command; -use cross::shell::MessageInfo; use cross::{docker, CommandExt, ToUtf8}; +use cross::{docker::ImagePlatform, shell::MessageInfo}; -use cross::docker::ImagePlatform; use once_cell::sync::{Lazy, OnceCell}; use serde::Deserialize; @@ -47,9 +46,9 @@ pub struct CiTarget { /// if `true` publish the generated binaries for cross #[serde(default)] pub deploy: Option, - /// the platform to build this image for, defaults to `["linux/amd64"]`, takes multiple + /// the platform to build this image for, defaults to whatever is needed, takes multiple #[serde(skip_serializing_if = "Option::is_none")] - platforms: Option>, + pub platforms: Option>, /// if `true` signal that this target requires `-Zbuild-std` #[serde(skip_serializing_if = "Option::is_none")] pub build_std: Option, @@ -83,6 +82,8 @@ impl CiTarget { crate::ImageTarget { name: self.target.clone(), sub: self.sub.clone(), + // XXX: This does not align with platforms() by design, as we want to be able to know if the field was set or not. + platform: self.platforms.clone(), } } @@ -163,6 +164,7 @@ pub fn pull_image( pub struct ImageTarget { pub name: String, pub sub: Option, + pub platform: Option>, } impl ImageTarget { @@ -236,6 +238,7 @@ impl std::str::FromStr for ImageTarget { return Ok(ImageTarget { name: target.to_string(), sub: Some(sub.to_string()), + platform: None, }); } } @@ -243,6 +246,7 @@ impl std::str::FromStr for ImageTarget { Ok(ImageTarget { name: s.to_string(), sub: None, + platform: None, }) } } @@ -383,6 +387,7 @@ mod tests { ImageTarget { name: "x86_64-unknown-linux-gnu".to_owned(), sub: None, + platform: None, }, "x86_64-unknown-linux-gnu".parse().unwrap() ); @@ -390,6 +395,7 @@ mod tests { ImageTarget { name: "x86_64-unknown-linux-gnu".to_owned(), sub: Some("centos".to_owned()), + platform: None, }, "x86_64-unknown-linux-gnu.centos".parse().unwrap() ); @@ -397,6 +403,7 @@ mod tests { ImageTarget { name: "thumbv8m.main-none-eabihf".to_owned(), sub: None, + platform: None, }, "thumbv8m.main-none-eabihf".parse().unwrap() ); @@ -404,6 +411,7 @@ mod tests { ImageTarget { name: "thumbv8m.main-unknown-linux-gnueabihf".to_owned(), sub: Some("alpine".to_owned()), + platform: None, }, "thumbv8m.main-unknown-linux-gnueabihf.alpine" .parse()