flowey_lib_hvlite/
build_openhcl_boot.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Build `openhcl_boot` binaries
5
6use crate::run_cargo_build::BuildProfile;
7use crate::run_cargo_build::common::CommonArch;
8use flowey::node::prelude::*;
9use std::collections::BTreeMap;
10
11#[derive(Serialize, Deserialize)]
12pub struct OpenhclBootOutput {
13    pub bin: PathBuf,
14    pub dbg: PathBuf,
15}
16
17#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
18pub enum OpenhclBootBuildProfile {
19    Debug,
20    Release,
21}
22
23#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
24pub struct OpenhclBootBuildParams {
25    pub arch: CommonArch,
26    pub profile: OpenhclBootBuildProfile,
27}
28
29flowey_request! {
30    pub struct Request {
31        pub build_params: OpenhclBootBuildParams,
32        pub openhcl_boot: WriteVar<OpenhclBootOutput>,
33    }
34}
35
36new_flow_node!(struct Node);
37
38impl FlowNode for Node {
39    type Request = Request;
40
41    fn imports(ctx: &mut ImportCtx<'_>) {
42        ctx.import::<crate::run_cargo_build::Node>();
43    }
44
45    fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
46        // de-dupe incoming requests
47        let requests = requests
48            .into_iter()
49            .fold(BTreeMap::<_, Vec<_>>::new(), |mut m, r| {
50                let Request {
51                    build_params,
52                    openhcl_boot,
53                } = r;
54                m.entry(build_params).or_default().push(openhcl_boot);
55                m
56            });
57
58        for (OpenhclBootBuildParams { arch, profile }, openhcl_boot) in requests {
59            let target = match arch {
60                CommonArch::X86_64 => target_lexicon::Triple {
61                    architecture: arch.as_arch(),
62                    operating_system: target_lexicon::OperatingSystem::None_,
63                    environment: target_lexicon::Environment::Unknown,
64                    vendor: target_lexicon::Vendor::Unknown,
65                    binary_format: target_lexicon::BinaryFormat::Unknown,
66                },
67                CommonArch::Aarch64 => target_lexicon::Triple {
68                    architecture: arch.as_arch(),
69                    operating_system: target_lexicon::OperatingSystem::Linux,
70                    environment: target_lexicon::Environment::Musl,
71                    vendor: target_lexicon::Vendor::Unknown,
72                    binary_format: target_lexicon::BinaryFormat::Elf,
73                },
74            };
75
76            // We use special profiles for boot, convert from the standard ones:
77            let profile = match profile {
78                OpenhclBootBuildProfile::Debug => BuildProfile::BootDev,
79                OpenhclBootBuildProfile::Release => BuildProfile::BootRelease,
80            };
81
82            let output = ctx.reqv(|v| crate::run_cargo_build::Request {
83                crate_name: "openhcl_boot".into(),
84                out_name: "openhcl_boot".into(),
85                crate_type: flowey_lib_common::run_cargo_build::CargoCrateType::Bin,
86                profile,
87                features: Default::default(),
88                target,
89                no_split_dbg_info: false,
90                extra_env: Some(ReadVar::from_static(
91                    [("MINIMAL_RT_BUILD".to_string(), "1".to_string())]
92                        .into_iter()
93                        .collect(),
94                )),
95                pre_build_deps: Vec::new(),
96                output: v,
97            });
98
99            ctx.emit_minor_rust_step("report built openhcl_boot", |ctx| {
100                let openhcl_boot = openhcl_boot.claim(ctx);
101                let output = output.claim(ctx);
102                move |rt| {
103                    let output = match rt.read(output) {
104                        crate::run_cargo_build::CargoBuildOutput::ElfBin { bin, dbg } => {
105                            OpenhclBootOutput {
106                                bin,
107                                dbg: dbg.unwrap(),
108                            }
109                        }
110                        _ => unreachable!(),
111                    };
112
113                    for var in openhcl_boot {
114                        rt.write(var, &output);
115                    }
116                }
117            });
118        }
119
120        Ok(())
121    }
122}