Skip to main content

flowey_lib_hvlite/
build_opentmk.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Build `opentmk` UEFI binaries
5
6use crate::common::CommonArch;
7use crate::common::CommonProfile;
8use flowey::node::prelude::*;
9use flowey_lib_common::run_cargo_build::CargoCrateType;
10use std::collections::BTreeMap;
11
12#[derive(Serialize, Deserialize)]
13pub struct OpentmkOutput {
14    pub efi: PathBuf,
15    pub pdb: PathBuf,
16}
17
18impl Artifact for OpentmkOutput {}
19
20flowey_request! {
21    pub struct Request {
22        pub arch: CommonArch,
23        pub profile: CommonProfile,
24        /// Custom output `.efi`/`.pdb` name. Defaults to "opentmk".
25        pub out_name: Option<String>,
26        pub opentmk: WriteVar<OpentmkOutput>,
27    }
28}
29
30new_flow_node!(struct Node);
31
32impl FlowNode for Node {
33    type Request = Request;
34
35    fn imports(ctx: &mut ImportCtx<'_>) {
36        ctx.import::<crate::run_cargo_build::Node>();
37    }
38
39    fn emit(requests: Vec<Self::Request>, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
40        let mut tasks: BTreeMap<_, Vec<_>> = BTreeMap::new();
41
42        for Request {
43            arch,
44            profile,
45            out_name,
46            opentmk,
47        } in requests
48        {
49            let out_name = out_name.unwrap_or_else(|| "opentmk".to_string());
50            tasks
51                .entry((arch, profile, out_name))
52                .or_default()
53                .push(opentmk);
54        }
55
56        for ((arch, profile, out_name), outvars) in tasks {
57            let output = ctx.reqv(|v| crate::run_cargo_build::Request {
58                crate_name: "opentmk".into(),
59                out_name: out_name.clone(),
60                crate_type: CargoCrateType::Bin,
61                profile: profile.into(),
62                features: Default::default(),
63                target: target_lexicon::Triple {
64                    architecture: arch.as_arch(),
65                    operating_system: target_lexicon::OperatingSystem::Uefi,
66                    environment: target_lexicon::Environment::Unknown,
67                    vendor: target_lexicon::Vendor::Unknown,
68                    // work around bug in target_lexicon (this shouldn't be Elf)
69                    binary_format: target_lexicon::BinaryFormat::Elf,
70                },
71                no_split_dbg_info: false,
72                extra_env: None,
73                pre_build_deps: Vec::new(),
74                output: v,
75            });
76
77            ctx.emit_minor_rust_step("report built opentmk", |ctx| {
78                let outvars = outvars.claim(ctx);
79                let output = output.claim(ctx);
80                move |rt| {
81                    let (efi, pdb) = match rt.read(output) {
82                        crate::run_cargo_build::CargoBuildOutput::UefiBin { efi, pdb } => {
83                            (efi, pdb)
84                        }
85                        _ => unreachable!(),
86                    };
87
88                    let output = OpentmkOutput { efi, pdb };
89
90                    for var in outvars {
91                        rt.write(var, &output);
92                    }
93                }
94            });
95        }
96
97        Ok(())
98    }
99}