flowey_lib_hvlite/
build_openvmm.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Build `openvmm` binaries
5
6use crate::run_cargo_build::common::CommonProfile;
7use crate::run_cargo_build::common::CommonTriple;
8use flowey::node::prelude::*;
9use flowey_lib_common::run_cargo_build::CargoFeatureSet;
10use std::collections::BTreeSet;
11
12#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
13pub enum OpenvmmFeature {
14    Gdb,
15    Tpm,
16    UnstableWhp,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
20pub struct OpenvmmBuildParams {
21    pub profile: CommonProfile,
22    pub target: CommonTriple,
23    pub features: BTreeSet<OpenvmmFeature>,
24}
25
26#[derive(Serialize, Deserialize)]
27#[serde(untagged)]
28pub enum OpenvmmOutput {
29    WindowsBin {
30        #[serde(rename = "openvmm.exe")]
31        exe: PathBuf,
32        #[serde(rename = "openvmm.pdb")]
33        pdb: PathBuf,
34    },
35    LinuxBin {
36        #[serde(rename = "openvmm")]
37        bin: PathBuf,
38        #[serde(rename = "openvmm.dbg")]
39        dbg: PathBuf,
40    },
41}
42
43impl Artifact for OpenvmmOutput {}
44
45flowey_request! {
46    pub struct Request {
47        pub params: OpenvmmBuildParams,
48        pub openvmm: WriteVar<OpenvmmOutput>,
49    }
50}
51
52new_flow_node!(struct Node);
53
54impl FlowNode for Node {
55    type Request = Request;
56
57    fn imports(ctx: &mut ImportCtx<'_>) {
58        ctx.import::<crate::run_cargo_build::Node>();
59        ctx.import::<flowey_lib_common::install_dist_pkg::Node>();
60    }
61
62    fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
63        let mut pre_build_deps = Vec::new();
64
65        // TODO: install build tools for other platforms
66        if matches!(
67            ctx.platform(),
68            FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu)
69        ) {
70            pre_build_deps.push(ctx.reqv(|v| {
71                flowey_lib_common::install_dist_pkg::Request::Install {
72                    package_names: vec!["libssl-dev".into(), "build-essential".into()],
73                    done: v,
74                }
75            }));
76        }
77
78        for Request {
79            params:
80                OpenvmmBuildParams {
81                    profile,
82                    target,
83                    features,
84                },
85            openvmm: openvmm_bin,
86        } in requests
87        {
88            let output = ctx.reqv(|v| crate::run_cargo_build::Request {
89                crate_name: "openvmm".into(),
90                out_name: "openvmm".into(),
91                crate_type: flowey_lib_common::run_cargo_build::CargoCrateType::Bin,
92                profile: profile.into(),
93                features: CargoFeatureSet::Specific(
94                    features
95                        .into_iter()
96                        .map(|f| {
97                            match f {
98                                OpenvmmFeature::Gdb => "gdb",
99                                OpenvmmFeature::Tpm => "tpm",
100                                OpenvmmFeature::UnstableWhp => "unstable_whp",
101                            }
102                            .into()
103                        })
104                        .collect(),
105                ),
106                target: target.as_triple(),
107                no_split_dbg_info: false,
108                extra_env: None,
109                pre_build_deps: pre_build_deps.clone(),
110                output: v,
111            });
112
113            ctx.emit_minor_rust_step("report built openvmm", |ctx| {
114                let openvmm_bin = openvmm_bin.claim(ctx);
115                let output = output.claim(ctx);
116                move |rt| {
117                    let output = match rt.read(output) {
118                        crate::run_cargo_build::CargoBuildOutput::WindowsBin { exe, pdb } => {
119                            OpenvmmOutput::WindowsBin { exe, pdb }
120                        }
121                        crate::run_cargo_build::CargoBuildOutput::ElfBin { bin, dbg } => {
122                            OpenvmmOutput::LinuxBin {
123                                bin,
124                                dbg: dbg.unwrap(),
125                            }
126                        }
127                        _ => unreachable!(),
128                    };
129
130                    rt.write(openvmm_bin, &output);
131                }
132            });
133        }
134
135        Ok(())
136    }
137}