Skip to main content

flowey_lib_hvlite/
build_guest_test_uefi.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Build `guest_test_uefi` images and binaries
5
6use crate::common::CommonArch;
7use crate::common::CommonProfile;
8use flowey::node::prelude::*;
9use flowey_lib_common::_util::group_by;
10use flowey_lib_common::run_cargo_build::CargoCrateType;
11
12#[derive(Serialize, Deserialize)]
13pub struct GuestTestUefiOutput {
14    #[serde(rename = "guest_test_uefi.efi")]
15    pub efi: Option<PathBuf>,
16    #[serde(rename = "guest_test_uefi.pdb")]
17    pub pdb: Option<PathBuf>,
18    #[serde(rename = "guest_test_uefi.img")]
19    pub img: PathBuf,
20}
21
22impl Artifact for GuestTestUefiOutput {}
23
24flowey_request! {
25    pub struct Request {
26        pub arch: CommonArch,
27        pub profile: CommonProfile,
28        pub guest_test_uefi: WriteVar<GuestTestUefiOutput>,
29    }
30}
31
32new_flow_node!(struct Node);
33
34impl FlowNode for Node {
35    type Request = Request;
36
37    fn imports(ctx: &mut ImportCtx<'_>) {
38        ctx.import::<crate::run_cargo_build::Node>();
39        ctx.import::<crate::git_checkout_openvmm_repo::Node>();
40    }
41
42    fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
43        let tasks = group_by(
44            requests
45                .into_iter()
46                .map(|r| ((r.arch, r.profile), r.guest_test_uefi)),
47        );
48
49        for ((arch, profile), outvars) in tasks {
50            let output = ctx.reqv(|v| {
51                crate::run_cargo_build::Request {
52                    crate_name: "guest_test_uefi".into(),
53                    out_name: "guest_test_uefi".into(),
54                    crate_type: CargoCrateType::Bin,
55                    profile: profile.into(),
56                    features: Default::default(),
57                    target: target_lexicon::Triple {
58                        architecture: arch.as_arch(),
59                        operating_system: target_lexicon::OperatingSystem::Uefi,
60                        environment: target_lexicon::Environment::Unknown,
61                        vendor: target_lexicon::Vendor::Unknown,
62                        // work around bug in target_lexicon (this shouldn't be Elf)
63                        binary_format: target_lexicon::BinaryFormat::Elf,
64                    },
65                    no_split_dbg_info: false,
66                    extra_env: None,
67                    pre_build_deps: Vec::new(),
68                    output: v,
69                }
70            });
71
72            let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir);
73
74            ctx.emit_rust_step("build guest_test_uefi.img", |ctx| {
75                let openvmm_repo_path = openvmm_repo_path.claim(ctx);
76                let output = output.claim(ctx);
77                let outvars = outvars.claim(ctx);
78                move |rt| {
79                    let (efi, pdb) = match rt.read(output) {
80                        crate::run_cargo_build::CargoBuildOutput::UefiBin { efi, pdb } => {
81                            (efi, pdb)
82                        }
83                        _ => unreachable!(),
84                    };
85
86                    // package it up into an img using the xtask
87                    let img_path = rt.sh.current_dir().join("guest_test_uefi.img");
88                    let arch_arg = match arch {
89                        CommonArch::X86_64 => "bootx64",
90                        CommonArch::Aarch64 => "bootaa64",
91                    };
92                    let path = rt.read(openvmm_repo_path);
93                    rt.sh.change_dir(path);
94                    flowey::shell_cmd!(
95                        rt,
96                        "cargo xtask guest-test uefi --output {img_path} --{arch_arg} {efi}"
97                    )
98                    .run()?;
99
100                    let output = GuestTestUefiOutput {
101                        efi: Some(efi),
102                        pdb: Some(pdb),
103                        img: img_path.absolute()?,
104                    };
105
106                    rt.write_all(outvars, &output);
107
108                    Ok(())
109                }
110            });
111        }
112
113        Ok(())
114    }
115}