flowey_lib_hvlite/
build_openhcl_boot.rs1use crate::common::CommonArch;
7use crate::run_cargo_build::BuildProfile;
8use flowey::node::prelude::*;
9use flowey_lib_common::run_cargo_build::CargoFeatureSet;
10use std::collections::BTreeMap;
11
12#[derive(Serialize, Deserialize)]
13pub struct OpenhclBootOutput {
14 #[serde(rename = "openhcl_boot")]
15 pub bin: PathBuf,
16 #[serde(rename = "openhcl_boot.dbg")]
17 pub dbg: PathBuf,
18}
19
20#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
21pub enum OpenhclBootBuildProfile {
22 Debug,
23 Release,
24}
25
26#[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
27pub struct OpenhclBootBuildParams {
28 pub arch: CommonArch,
29 pub profile: OpenhclBootBuildProfile,
30}
31
32flowey_request! {
33 pub struct Request {
34 pub build_params: OpenhclBootBuildParams,
35 pub openhcl_boot: WriteVar<OpenhclBootOutput>,
36 }
37}
38
39new_flow_node!(struct Node);
40
41impl FlowNode for Node {
42 type Request = Request;
43
44 fn imports(ctx: &mut ImportCtx<'_>) {
45 ctx.import::<crate::run_cargo_build::Node>();
46 }
47
48 fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
49 let requests = requests
51 .into_iter()
52 .fold(BTreeMap::<_, Vec<_>>::new(), |mut m, r| {
53 let Request {
54 build_params,
55 openhcl_boot,
56 } = r;
57 m.entry(build_params).or_default().push(openhcl_boot);
58 m
59 });
60
61 for (OpenhclBootBuildParams { arch, profile }, openhcl_boot) in requests {
62 let target = target_lexicon::Triple {
63 architecture: arch.as_arch(),
64 operating_system: target_lexicon::OperatingSystem::None_,
65 environment: target_lexicon::Environment::Unknown,
66 vendor: target_lexicon::Vendor::Custom(target_lexicon::CustomVendor::Static(
67 "minimal_rt",
68 )),
69 binary_format: target_lexicon::BinaryFormat::Unknown,
70 };
71
72 let profile = match profile {
74 OpenhclBootBuildProfile::Debug => BuildProfile::BootDev,
75 OpenhclBootBuildProfile::Release => BuildProfile::BootRelease,
76 };
77
78 let features = if matches!(profile, BuildProfile::BootDev) {
81 CargoFeatureSet::Specific(vec!["cvm_boot_log".into()])
82 } else {
83 CargoFeatureSet::None
84 };
85
86 let output = ctx.reqv(|v| crate::run_cargo_build::Request {
87 crate_name: "openhcl_boot".into(),
88 out_name: "openhcl_boot".into(),
89 crate_type: flowey_lib_common::run_cargo_build::CargoCrateType::Bin,
90 profile,
91 features,
92 target,
93 no_split_dbg_info: false,
94 extra_env: Some(ReadVar::from_static(
95 [
96 ("RUSTC_BOOTSTRAP".to_string(), "1".to_string()),
97 ("CC_FORCE_DISABLE".to_string(), "1".to_string()),
98 (
99 "CMAKE".to_string(),
100 "cmake-is-forbidden-during-openvmm-hcl-build".to_string(),
101 ),
102 ]
103 .into_iter()
104 .collect(),
105 )),
106 pre_build_deps: Vec::new(),
107 output: v,
108 });
109
110 ctx.emit_minor_rust_step("report built openhcl_boot", |ctx| {
111 let openhcl_boot = openhcl_boot.claim(ctx);
112 let output = output.claim(ctx);
113 move |rt| {
114 let output = match rt.read(output) {
115 crate::run_cargo_build::CargoBuildOutput::ElfBin { bin, dbg } => {
116 OpenhclBootOutput {
117 bin,
118 dbg: dbg.unwrap(),
119 }
120 }
121 _ => unreachable!(),
122 };
123
124 for var in openhcl_boot {
125 rt.write(var, &output);
126 }
127 }
128 });
129 }
130
131 Ok(())
132 }
133}