1use crate::download_lxutil::LxutilArch;
7use crate::init_openvmm_magicpath_openhcl_sysroot::OpenvmmSysrootArch;
8use crate::run_cargo_build::common::CommonArch;
9use crate::run_cargo_build::common::CommonPlatform;
10use crate::run_cargo_build::common::CommonProfile;
11use crate::run_cargo_build::common::CommonTriple;
12use flowey::node::prelude::*;
13use flowey_lib_common::run_cargo_build::CargoBuildProfile;
14use flowey_lib_common::run_cargo_build::CargoFeatureSet;
15use flowey_lib_common::run_cargo_clippy::CargoPackage;
16
17flowey_request! {
18 pub struct Request {
19 pub target: target_lexicon::Triple,
20 pub profile: CommonProfile,
21 pub done: WriteVar<SideEffect>,
22 pub also_check_misc_nostd_crates: bool,
23 }
24}
25
26new_simple_flow_node!(struct Node);
27
28impl SimpleFlowNode for Node {
29 type Request = Request;
30
31 fn imports(ctx: &mut ImportCtx<'_>) {
32 ctx.import::<crate::build_xtask::Node>();
33 ctx.import::<crate::git_checkout_openvmm_repo::Node>();
34 ctx.import::<crate::init_openvmm_magicpath_openhcl_sysroot::Node>();
35 ctx.import::<crate::init_openvmm_magicpath_lxutil::Node>();
36 ctx.import::<crate::install_openvmm_rust_build_essential::Node>();
37 ctx.import::<crate::init_cross_build::Node>();
38 ctx.import::<flowey_lib_common::install_rust::Node>();
39 ctx.import::<flowey_lib_common::install_dist_pkg::Node>();
40 ctx.import::<flowey_lib_common::run_cargo_clippy::Node>();
41 }
42
43 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
44 let Request {
45 target,
46 profile,
47 done,
48 also_check_misc_nostd_crates,
49 } = request;
50
51 let flowey_platform = ctx.platform();
52 let flowey_arch = ctx.arch();
53
54 let (boot_target, uefi_target, sysroot_arch, lxutil_arch) = match target.architecture {
55 target_lexicon::Architecture::X86_64 => (
56 "x86_64-unknown-none",
57 "x86_64-unknown-uefi",
58 OpenvmmSysrootArch::X64,
59 LxutilArch::X86_64,
60 ),
61 target_lexicon::Architecture::Aarch64(_) => (
62 "aarch64-unknown-linux-musl",
63 "aarch64-unknown-uefi",
64 OpenvmmSysrootArch::Aarch64,
65 LxutilArch::Aarch64,
66 ),
67 arch => anyhow::bail!("unsupported arch {arch}"),
68 };
69
70 let mut pre_build_deps = Vec::new();
71
72 if matches!(target.environment, target_lexicon::Environment::Musl) {
77 pre_build_deps.push(
78 ctx.reqv(|v| crate::init_openvmm_magicpath_openhcl_sysroot::Request {
79 arch: sysroot_arch,
80 path: v,
81 })
82 .into_side_effect(),
83 );
84 }
85
86 pre_build_deps.push(ctx.reqv(|v| crate::init_openvmm_magicpath_lxutil::Request {
88 arch: lxutil_arch,
89 done: v,
90 }));
91
92 ctx.req(flowey_lib_common::install_rust::Request::InstallTargetTriple(target.clone()));
93 if also_check_misc_nostd_crates {
94 ctx.req(
95 flowey_lib_common::install_rust::Request::InstallTargetTriple(
96 target_lexicon::triple!(uefi_target),
97 ),
98 );
99 ctx.req(
100 flowey_lib_common::install_rust::Request::InstallTargetTriple(
101 target_lexicon::triple!(boot_target),
102 ),
103 );
104 }
105
106 pre_build_deps.push(
107 ctx.reqv(|v| flowey_lib_common::install_dist_pkg::Request::Install {
108 package_names: vec!["libssl-dev".into()],
109 done: v,
110 }),
111 );
112
113 pre_build_deps.push(ctx.reqv(crate::install_openvmm_rust_build_essential::Request));
114
115 if !matches!(
118 target.operating_system,
119 target_lexicon::OperatingSystem::Darwin(_)
120 ) {
121 pre_build_deps.push(
122 ctx.reqv(|v| crate::init_cross_build::Request {
123 target: target.clone(),
124 injected_env: v,
125 })
126 .into_side_effect(),
127 );
128 }
129
130 let xtask_target = CommonTriple::Common {
131 arch: match flowey_arch {
132 FlowArch::X86_64 => CommonArch::X86_64,
133 FlowArch::Aarch64 => CommonArch::Aarch64,
134 arch => anyhow::bail!("unsupported arch {arch}"),
135 },
136 platform: match flowey_platform {
137 FlowPlatform::Windows => CommonPlatform::WindowsMsvc,
138 FlowPlatform::Linux(_) => CommonPlatform::LinuxGnu,
139 FlowPlatform::MacOs => CommonPlatform::MacOs,
140 platform => anyhow::bail!("unsupported platform {platform}"),
141 },
142 };
143
144 let xtask = ctx.reqv(|v| crate::build_xtask::Request {
145 target: xtask_target,
146 xtask: v,
147 });
148
149 let profile = match profile {
150 CommonProfile::Release => CargoBuildProfile::Release,
151 CommonProfile::Debug => CargoBuildProfile::Debug,
152 };
153
154 let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir);
155
156 let exclude = ctx.emit_rust_stepv("determine clippy exclusions", |ctx| {
157 let xtask = xtask.claim(ctx);
158 let repo_path = openvmm_repo_path.clone().claim(ctx);
159 move |rt| {
160 let xtask = rt.read(xtask);
161 let repo_path = rt.read(repo_path);
162
163 let mut exclude = vec!["guest_test_uefi".into()];
164
165 if !(matches!(target.architecture, target_lexicon::Architecture::X86_64)
167 && matches!(flowey_arch, FlowArch::X86_64))
168 {
169 let xtask_bin = match xtask {
170 crate::build_xtask::XtaskOutput::LinuxBin { bin, dbg: _ } => bin,
171 crate::build_xtask::XtaskOutput::WindowsBin { exe, pdb: _ } => exe,
172 };
173
174 let sh = xshell::Shell::new()?;
175 sh.change_dir(repo_path);
176 let output = xshell::cmd!(sh, "{xtask_bin} fuzz list --crates").output()?;
177 let output = String::from_utf8(output.stdout)?;
178
179 let fuzz_crates = output.trim().split('\n').map(|s| s.to_owned());
180 exclude.extend(fuzz_crates);
181
182 exclude.push("chipset_device_fuzz".into());
183 exclude.push("xtask_fuzz".into());
184 }
185
186 if matches!(
188 target.operating_system,
189 target_lexicon::OperatingSystem::Darwin(_)
190 ) {
191 exclude.extend(
192 ["openssl_kdf", "vmgs_lib", "block_crypto", "disk_crypt"].map(|x| x.into()),
193 );
194 }
195
196 Ok(Some(exclude))
197 }
198 });
199
200 let extra_env = if matches!(
201 target.operating_system,
202 target_lexicon::OperatingSystem::Darwin(_)
203 ) {
204 Some(vec![("SPARSE_MMAP_NO_BUILD".into(), "1".into())])
205 } else {
206 None
207 };
208
209 let features = if matches!(
216 target.operating_system,
217 target_lexicon::OperatingSystem::Windows | target_lexicon::OperatingSystem::Darwin(_)
218 ) {
219 CargoFeatureSet::None
220 } else {
221 CargoFeatureSet::All
222 };
223
224 let mut reqs = vec![ctx.reqv(|v| flowey_lib_common::run_cargo_clippy::Request {
225 in_folder: openvmm_repo_path.clone(),
226 package: CargoPackage::Workspace,
227 profile: profile.clone(),
228 features: features.clone(),
229 target,
230 extra_env,
231 exclude,
232 keep_going: true,
233 all_targets: true,
234 pre_build_deps: pre_build_deps.clone(),
235 done: v,
236 })];
237
238 if also_check_misc_nostd_crates {
239 reqs.push(ctx.reqv(|v| flowey_lib_common::run_cargo_clippy::Request {
240 in_folder: openvmm_repo_path.clone(),
241 package: CargoPackage::Crate("openhcl_boot".into()),
242 profile: profile.clone(),
243 features: features.clone(),
244 target: target_lexicon::triple!(boot_target),
245 extra_env: Some(vec![("MINIMAL_RT_BUILD".into(), "1".into())]),
246 exclude: ReadVar::from_static(None),
247 keep_going: true,
248 all_targets: false,
249 pre_build_deps: pre_build_deps.clone(),
250 done: v,
251 }));
252
253 reqs.push(ctx.reqv(|v| flowey_lib_common::run_cargo_clippy::Request {
255 in_folder: openvmm_repo_path.clone(),
256 package: CargoPackage::Crate("guest_test_uefi".into()),
257 profile: profile.clone(),
258 features,
259 target: target_lexicon::triple!(uefi_target),
260 extra_env: None,
261 exclude: ReadVar::from_static(None),
262 keep_going: true,
263 all_targets: false,
264 pre_build_deps: pre_build_deps.clone(),
265 done: v,
266 }));
267 }
268
269 ctx.emit_side_effect_step(reqs, [done]);
270
271 Ok(())
272 }
273}