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 ssl_pkg = match ctx.platform() {
60 FlowPlatform::Linux(
61 FlowPlatformLinuxDistro::Fedora | FlowPlatformLinuxDistro::AzureLinux,
62 ) => "openssl-devel",
63 _ => "libssl-dev",
64 };
65 let pre_build_deps =
66 [
67 ctx.reqv(|v| flowey_lib_common::install_dist_pkg::Request::Install {
68 package_names: vec![ssl_pkg.into()],
69 done: v,
70 }),
71 ]
72 .to_vec();
73
74 let output = ctx.reqv(|v| crate::run_cargo_build::Request {
75 crate_name: "vmgs_lib".into(),
76 out_name: "vmgs_lib".into(),
77 crate_type: CargoCrateType::DynamicLib,
78 profile: profile.into(),
79 features: Default::default(),
80 target: target.as_triple(),
81 no_split_dbg_info: false,
82 extra_env: None,
83 pre_build_deps,
84 output: v,
85 });
86
87 let built_vmgs_lib = ctx.emit_minor_rust_stepv("check built vmgs_lib", |ctx| {
88 let output = output.claim(ctx);
89 move |rt| match rt.read(output) {
90 CargoBuildOutput::LinuxDynamicLib { so } => VmgsLibOutput::LinuxDynamicLib { so },
91 CargoBuildOutput::WindowsDynamicLib { dll, dll_lib, pdb } => {
92 VmgsLibOutput::WindowsDynamicLib { dll, dll_lib, pdb }
93 }
94 _ => unreachable!(),
95 }
96 });
97
98 let did_test = if matches!(
107 &target.as_triple().architecture,
108 target_lexicon::Architecture::X86_64
109 ) && matches!(ctx.arch(), FlowArch::X86_64)
110 {
111 let clang_installed =
112 ctx.reqv(|v| flowey_lib_common::install_dist_pkg::Request::Install {
113 package_names: vec!["clang".into()],
114 done: v,
115 });
116
117 let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir);
118
119 if matches!(ctx.platform(), FlowPlatform::Linux(_)) {
120 ctx.emit_rust_step("test vmgs_lib", |ctx| {
121 clang_installed.claim(ctx);
122
123 let built_vmgs_lib = built_vmgs_lib.clone().claim(ctx);
124 let openvmm_repo_path = openvmm_repo_path.claim(ctx);
125
126 move |rt| {
127 let VmgsLibOutput::LinuxDynamicLib { so } = rt.read(built_vmgs_lib) else {
128 unreachable!()
129 };
130
131 let so_dir = so.parent().unwrap();
132
133 let openvmm_repo_path = rt.read(openvmm_repo_path);
134
135 let vmgs_testlib_c =
136 openvmm_repo_path.join("vm/vmgs/vmgs_lib/examples/vmgs_testlib.c");
137
138 if which::which("clang").is_ok() {
139 flowey::shell_cmd!(
140 rt,
141 "clang {vmgs_testlib_c} {so} -rpath {so_dir} -o ./vmgs_lib_test"
142 )
143 .run()?;
144 flowey::shell_cmd!(rt, "./vmgs_lib_test").run()?;
145 } else {
146 log::warn!("skipping vmgs_lib test (could not find clang)");
147 }
148
149 Ok(())
150 }
151 })
152 } else if matches!(ctx.platform(), FlowPlatform::Windows) {
153 ctx.emit_rust_step("test vmgs_lib", |ctx| {
158 clang_installed.claim(ctx);
159
160 let built_vmgs_lib = built_vmgs_lib.clone().claim(ctx);
161 let openvmm_repo_path = openvmm_repo_path.claim(ctx);
162
163 move |rt| {
164 if flowey_lib_common::_util::running_in_wsl(rt)
166 && matches!(
167 &target.as_triple().operating_system,
168 target_lexicon::OperatingSystem::Windows
169 )
170 {
171 log::warn!("unimplemented: skip testing windows vmgs_lib via WSL2");
172 return Ok(());
173 }
174
175 let openvmm_repo_path = rt.read(openvmm_repo_path);
176
177 let VmgsLibOutput::WindowsDynamicLib {
178 dll,
179 dll_lib,
180 pdb: _,
181 } = rt.read(built_vmgs_lib)
182 else {
183 unreachable!()
184 };
185
186 if which::which("clang").is_err() {
187 log::warn!("skipping vmgs_lib test (could not find clang)");
188 return Ok(());
189 }
190
191 let vmgs_testlib_c =
192 openvmm_repo_path.join("vm/vmgs/vmgs_lib/examples/vmgs_testlib.c");
193
194 fs_err::copy(dll_lib, "vmgs_lib.dll.lib")?;
196 fs_err::copy(dll, "vmgs_lib.dll")?;
197
198 flowey::shell_cmd!(
199 rt,
200 "clang {vmgs_testlib_c} -o vmgs_lib_test.exe -l vmgs_lib.dll"
201 )
202 .run()?;
203 flowey::shell_cmd!(rt, "./vmgs_lib_test.exe").run()?;
204
205 Ok(())
206 }
207 })
208 } else {
209 anyhow::bail!("unsupported platform")
210 }
211 } else {
212 ReadVar::from_static(()).into_side_effect()
213 };
214
215 ctx.emit_minor_rust_step("report built vmgs_lib", |ctx| {
216 did_test.claim(ctx);
217 let built_vmgs_lib = built_vmgs_lib.claim(ctx);
218 let vmgs_lib = vmgs_lib.claim(ctx);
219 move |rt| {
220 let built_vmgs_lib = rt.read(built_vmgs_lib);
221 rt.write(vmgs_lib, &built_vmgs_lib);
222 }
223 });
224
225 Ok(())
226 }
227}