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: [].into(),
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 let sh = xshell::Shell::new()?;
134 xshell::cmd!(
135 sh,
136 "clang {vmgs_testlib_c} {so} -rpath {so_dir} -o ./vmgs_lib_test"
137 )
138 .run()?;
139 xshell::cmd!(sh, "./vmgs_lib_test").run()?;
140 } else {
141 log::warn!("skipping vmgs_lib test (could not find clang)");
142 }
143
144 Ok(())
145 }
146 })
147 } else if matches!(ctx.platform(), FlowPlatform::Windows) {
148 ctx.emit_rust_step("test vmgs_lib", |ctx| {
153 clang_installed.claim(ctx);
154
155 let built_vmgs_lib = built_vmgs_lib.clone().claim(ctx);
156 let openvmm_repo_path = openvmm_repo_path.claim(ctx);
157
158 move |rt| {
159 if flowey_lib_common::_util::running_in_wsl(rt)
161 && matches!(
162 &target.as_triple().operating_system,
163 target_lexicon::OperatingSystem::Windows
164 )
165 {
166 log::warn!("unimplemented: skip testing windows vmgs_lib via WSL2");
167 return Ok(());
168 }
169
170 let openvmm_repo_path = rt.read(openvmm_repo_path);
171
172 let VmgsLibOutput::WindowsDynamicLib {
173 dll,
174 dll_lib,
175 pdb: _,
176 } = rt.read(built_vmgs_lib)
177 else {
178 unreachable!()
179 };
180
181 if which::which("clang").is_err() {
182 log::warn!("skipping vmgs_lib test (could not find clang)");
183 return Ok(());
184 }
185
186 let vmgs_testlib_c =
187 openvmm_repo_path.join("vm/vmgs/vmgs_lib/examples/vmgs_testlib.c");
188
189 fs_err::copy(dll_lib, "vmgs_lib.dll.lib")?;
191 fs_err::copy(dll, "vmgs_lib.dll")?;
192
193 let sh = xshell::Shell::new()?;
194 xshell::cmd!(
195 sh,
196 "clang {vmgs_testlib_c} -o vmgs_lib_test.exe -l vmgs_lib.dll"
197 )
198 .run()?;
199 xshell::cmd!(sh, "./vmgs_lib_test.exe").run()?;
200
201 Ok(())
202 }
203 })
204 } else {
205 anyhow::bail!("unsupported platform")
206 }
207 } else {
208 ReadVar::from_static(()).into_side_effect()
209 };
210
211 ctx.emit_minor_rust_step("report built vmgs_lib", |ctx| {
212 did_test.claim(ctx);
213 let built_vmgs_lib = built_vmgs_lib.claim(ctx);
214 let vmgs_lib = vmgs_lib.claim(ctx);
215 move |rt| {
216 let built_vmgs_lib = rt.read(built_vmgs_lib);
217 rt.write(vmgs_lib, &built_vmgs_lib);
218 }
219 });
220
221 Ok(())
222 }
223}