flowey_lib_hvlite/
build_vmfirmwareigvm_dll.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Build an instance of `vmfirmwareigvm.dll`
5
6use crate::run_cargo_build::common::CommonArch;
7use crate::run_cargo_build::common::CommonTriple;
8use crate::run_igvmfilegen::IgvmOutput;
9use flowey::node::prelude::*;
10use std::collections::BTreeMap;
11
12#[derive(Serialize, Deserialize)]
13pub struct VmfirmwareigvmDllOutput {
14    pub dll: PathBuf,
15}
16
17flowey_request! {
18    pub struct Request {
19        pub arch: CommonArch,
20        pub igvm: ReadVar<IgvmOutput>,
21        /// (major, minor, patch, revision)
22        pub dll_version: ReadVar<(u16, u16, u16, u16)>,
23        pub internal_dll_name: String,
24        pub vmfirmwareigvm_dll: WriteVar<VmfirmwareigvmDllOutput>,
25    }
26}
27
28new_simple_flow_node!(struct Node);
29
30impl SimpleFlowNode for Node {
31    type Request = Request;
32
33    fn imports(ctx: &mut ImportCtx<'_>) {
34        ctx.import::<crate::run_cargo_build::Node>();
35    }
36
37    fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
38        let Request {
39            arch,
40            igvm,
41            internal_dll_name,
42            dll_version,
43            vmfirmwareigvm_dll,
44        } = request;
45
46        let extra_env = ctx.emit_rust_stepv("determine vmfirmwareigvm_dll env vars", |ctx| {
47            let igvm = igvm.claim(ctx);
48            let dll_version = dll_version.claim(ctx);
49            move |rt| {
50                let mut extra_env = BTreeMap::new();
51
52                // set the various build-time env vars `vmfirmwareigvm_dll` expects
53                {
54                    extra_env.insert("UH_DLL_NAME".into(), internal_dll_name);
55                    extra_env.insert(
56                        "UH_IGVM_PATH".into(),
57                        // rc.exe treats '\' in windows paths as escape sequences.
58                        // there is likely a more robust solution to fix this, but
59                        // a simple swap from '\' to '/' seems to work fine for now
60                        rt.read(igvm)
61                            .igvm_bin
62                            .absolute()
63                            .context("Failed to make igvm bin path absolute")?
64                            .display()
65                            .to_string()
66                            .replace('\\', "/"),
67                    );
68                    let (major, minor, patch, revision) = rt.read(dll_version);
69                    extra_env.insert("UH_MAJOR".into(), major.to_string());
70                    extra_env.insert("UH_MINOR".into(), minor.to_string());
71                    extra_env.insert("UH_PATCH".into(), patch.to_string());
72                    extra_env.insert("UH_REVISION".into(), revision.to_string());
73                }
74
75                // workaround for the fact that hvlite's root-level `.cargo/config.toml`
76                // currently sets a bunch of extraneous linker flags via
77                //
78                // [target.'cfg(all(windows, target_env = "msvc"))']
79                extra_env.insert("RUSTFLAGS".into(), "".into());
80
81                Ok(extra_env)
82            }
83        });
84
85        let output = ctx.reqv(|v| crate::run_cargo_build::Request {
86            crate_name: "vmfirmwareigvm_dll".into(),
87            out_name: "vmfirmwareigvm_dll".into(),
88            crate_type: flowey_lib_common::run_cargo_build::CargoCrateType::DynamicLib,
89            profile: crate::run_cargo_build::BuildProfile::Release,
90            features: Default::default(),
91            target: CommonTriple::Common {
92                arch,
93                platform: crate::run_cargo_build::common::CommonPlatform::WindowsMsvc,
94            }
95            .as_triple(),
96            no_split_dbg_info: false,
97            extra_env: Some(extra_env),
98            pre_build_deps: Vec::new(),
99            output: v,
100        });
101
102        ctx.emit_minor_rust_step("report built vmfirmwareigvm_dll", |ctx| {
103            let vmfirmwareigvm_dll = vmfirmwareigvm_dll.claim(ctx);
104            let output = output.claim(ctx);
105            move |rt| {
106                let output = match rt.read(output) {
107                    crate::run_cargo_build::CargoBuildOutput::WindowsDynamicLib {
108                        dll,
109                        // this is a resource dll, so these don't matter
110                        dll_lib: _,
111                        pdb: _,
112                    } => VmfirmwareigvmDllOutput { dll },
113                    _ => unreachable!(),
114                };
115
116                rt.write(vmfirmwareigvm_dll, &output);
117            }
118        });
119
120        Ok(())
121    }
122}