flowey_lib_hvlite/
build_and_test_vmgs_lib.rs1use crate::run_cargo_build::CargoBuildOutput;
9use crate::run_cargo_build::common::CommonProfile;
10use crate::run_cargo_build::common::CommonTriple;
11use flowey::node::prelude::*;
12use flowey_lib_common::run_cargo_build::CargoCrateType;
13
14#[derive(Serialize, Deserialize)]
15#[serde(untagged)]
16pub enum VmgsLibOutput {
17 LinuxDynamicLib {
18 #[serde(rename = "libvmgs_lib.so")]
19 so: PathBuf,
20 },
21 WindowsDynamicLib {
22 #[serde(rename = "vmgs_lib.dll")]
23 dll: PathBuf,
24 #[serde(rename = "vmgs_lib.dll.lib")]
25 dll_lib: PathBuf,
26 #[serde(rename = "vmgs_lib.pdb")]
27 pdb: PathBuf,
28 },
29}
30
31impl Artifact for VmgsLibOutput {}
32
33flowey_request! {
34 pub struct Request {
35 pub target: CommonTriple,
36 pub profile: CommonProfile,
37 pub vmgs_lib: WriteVar<VmgsLibOutput>,
38 }
39}
40
41new_simple_flow_node!(struct Node);
42
43impl SimpleFlowNode for Node {
44 type Request = Request;
45
46 fn imports(ctx: &mut ImportCtx<'_>) {
47 ctx.import::<crate::run_cargo_build::Node>();
48 ctx.import::<crate::git_checkout_openvmm_repo::Node>();
49 ctx.import::<flowey_lib_common::install_dist_pkg::Node>();
50 }
51
52 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
53 let Request {
54 target,
55 profile,
56 vmgs_lib,
57 } = request;
58
59 let pre_build_deps =
60 [
61 ctx.reqv(|v| flowey_lib_common::install_dist_pkg::Request::Install {
62 package_names: vec!["libssl-dev".into()],
63 done: v,
64 }),
65 ]
66 .to_vec();
67
68 let output = ctx.reqv(|v| crate::run_cargo_build::Request {
69 crate_name: "vmgs_lib".into(),
70 out_name: "vmgs_lib".into(),
71 crate_type: CargoCrateType::DynamicLib,
72 profile: profile.into(),
73 features: Default::default(),
74 target: target.as_triple(),
75 no_split_dbg_info: false,
76 extra_env: None,
77 pre_build_deps,
78 output: v,
79 });
80
81 let built_vmgs_lib = ctx.emit_minor_rust_stepv("check built vmgs_lib", |ctx| {
82 let output = output.claim(ctx);
83 move |rt| match rt.read(output) {
84 CargoBuildOutput::LinuxDynamicLib { so } => VmgsLibOutput::LinuxDynamicLib { so },
85 CargoBuildOutput::WindowsDynamicLib { dll, dll_lib, pdb } => {
86 VmgsLibOutput::WindowsDynamicLib { dll, dll_lib, pdb }
87 }
88 _ => unreachable!(),
89 }
90 });
91
92 let did_test = if matches!(
101 &target.as_triple().architecture,
102 target_lexicon::Architecture::X86_64
103 ) && matches!(ctx.arch(), FlowArch::X86_64)
104 {
105 let clang_installed =
106 ctx.reqv(|v| flowey_lib_common::install_dist_pkg::Request::Install {
107 package_names: vec!["clang".into()],
108 done: v,
109 });
110
111 let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir);
112
113 if matches!(ctx.platform(), FlowPlatform::Linux(_)) {
114 ctx.emit_rust_step("test vmgs_lib", |ctx| {
115 clang_installed.claim(ctx);
116
117 let built_vmgs_lib = built_vmgs_lib.clone().claim(ctx);
118 let openvmm_repo_path = openvmm_repo_path.claim(ctx);
119
120 move |rt| {
121 let VmgsLibOutput::LinuxDynamicLib { so } = rt.read(built_vmgs_lib) else {
122 unreachable!()
123 };
124
125 let so_dir = so.parent().unwrap();
126
127 let openvmm_repo_path = rt.read(openvmm_repo_path);
128
129 let vmgs_testlib_c =
130 openvmm_repo_path.join("vm/vmgs/vmgs_lib/examples/vmgs_testlib.c");
131
132 if which::which("clang").is_ok() {
133 flowey::shell_cmd!(
134 rt,
135 "clang {vmgs_testlib_c} {so} -rpath {so_dir} -o ./vmgs_lib_test"
136 )
137 .run()?;
138 flowey::shell_cmd!(rt, "./vmgs_lib_test").run()?;
139 } else {
140 log::warn!("skipping vmgs_lib test (could not find clang)");
141 }
142
143 Ok(())
144 }
145 })
146 } else if matches!(ctx.platform(), FlowPlatform::Windows) {
147 ctx.emit_rust_step("test vmgs_lib", |ctx| {
152 clang_installed.claim(ctx);
153
154 let built_vmgs_lib = built_vmgs_lib.clone().claim(ctx);
155 let openvmm_repo_path = openvmm_repo_path.claim(ctx);
156
157 move |rt| {
158 if flowey_lib_common::_util::running_in_wsl(rt)
160 && matches!(
161 &target.as_triple().operating_system,
162 target_lexicon::OperatingSystem::Windows
163 )
164 {
165 log::warn!("unimplemented: skip testing windows vmgs_lib via WSL2");
166 return Ok(());
167 }
168
169 let openvmm_repo_path = rt.read(openvmm_repo_path);
170
171 let VmgsLibOutput::WindowsDynamicLib {
172 dll,
173 dll_lib,
174 pdb: _,
175 } = rt.read(built_vmgs_lib)
176 else {
177 unreachable!()
178 };
179
180 if which::which("clang").is_err() {
181 log::warn!("skipping vmgs_lib test (could not find clang)");
182 return Ok(());
183 }
184
185 let vmgs_testlib_c =
186 openvmm_repo_path.join("vm/vmgs/vmgs_lib/examples/vmgs_testlib.c");
187
188 fs_err::copy(dll_lib, "vmgs_lib.dll.lib")?;
190 fs_err::copy(dll, "vmgs_lib.dll")?;
191
192 flowey::shell_cmd!(
193 rt,
194 "clang {vmgs_testlib_c} -o vmgs_lib_test.exe -l vmgs_lib.dll"
195 )
196 .run()?;
197 flowey::shell_cmd!(rt, "./vmgs_lib_test.exe").run()?;
198
199 Ok(())
200 }
201 })
202 } else {
203 anyhow::bail!("unsupported platform")
204 }
205 } else {
206 ReadVar::from_static(()).into_side_effect()
207 };
208
209 ctx.emit_minor_rust_step("report built vmgs_lib", |ctx| {
210 did_test.claim(ctx);
211 let built_vmgs_lib = built_vmgs_lib.claim(ctx);
212 let vmgs_lib = vmgs_lib.claim(ctx);
213 move |rt| {
214 let built_vmgs_lib = rt.read(built_vmgs_lib);
215 rt.write(vmgs_lib, &built_vmgs_lib);
216 }
217 });
218
219 Ok(())
220 }
221}