Skip to main content

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::common::CommonProfile;
7use crate::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}
17
18#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
19pub struct OpenvmmBuildParams {
20    pub profile: CommonProfile,
21    pub target: CommonTriple,
22    pub features: BTreeSet<OpenvmmFeature>,
23}
24
25#[derive(Serialize, Deserialize)]
26#[serde(untagged)]
27pub enum OpenvmmOutput {
28    WindowsBin {
29        #[serde(rename = "openvmm.exe")]
30        exe: PathBuf,
31        #[serde(rename = "openvmm.pdb")]
32        #[serde(default, skip_serializing_if = "Option::is_none")]
33        pdb: Option<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(), "pkg-config".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                            }
101                            .into()
102                        })
103                        .collect(),
104                ),
105                target: target.as_triple(),
106                no_split_dbg_info: false,
107                extra_env: None,
108                pre_build_deps: pre_build_deps.clone(),
109                output: v,
110            });
111
112            ctx.emit_minor_rust_step("report built openvmm", |ctx| {
113                let openvmm_bin = openvmm_bin.claim(ctx);
114                let output = output.claim(ctx);
115                move |rt| {
116                    let output = match rt.read(output) {
117                        crate::run_cargo_build::CargoBuildOutput::WindowsBin { exe, pdb } => {
118                            OpenvmmOutput::WindowsBin { exe, pdb }
119                        }
120                        crate::run_cargo_build::CargoBuildOutput::ElfBin { bin, dbg } => {
121                            OpenvmmOutput::LinuxBin {
122                                bin,
123                                dbg: dbg.unwrap(),
124                            }
125                        }
126                        _ => unreachable!(),
127                    };
128
129                    rt.write(openvmm_bin, &output);
130                }
131            });
132        }
133
134        Ok(())
135    }
136}