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