xref: /aosp_15_r20/external/bazelbuild-rules_rust/tools/rust_analyzer/lib.rs (revision d4726bddaa87cc4778e7472feed243fa4b6c267f)
1*d4726bddSHONG Yifan use std::collections::HashMap;
2*d4726bddSHONG Yifan use std::path::Path;
3*d4726bddSHONG Yifan use std::process::Command;
4*d4726bddSHONG Yifan 
5*d4726bddSHONG Yifan use anyhow::anyhow;
6*d4726bddSHONG Yifan use runfiles::Runfiles;
7*d4726bddSHONG Yifan 
8*d4726bddSHONG Yifan mod aquery;
9*d4726bddSHONG Yifan mod rust_project;
10*d4726bddSHONG Yifan 
generate_crate_info( bazel: impl AsRef<Path>, workspace: impl AsRef<Path>, rules_rust: impl AsRef<str>, targets: &[String], ) -> anyhow::Result<()>11*d4726bddSHONG Yifan pub fn generate_crate_info(
12*d4726bddSHONG Yifan     bazel: impl AsRef<Path>,
13*d4726bddSHONG Yifan     workspace: impl AsRef<Path>,
14*d4726bddSHONG Yifan     rules_rust: impl AsRef<str>,
15*d4726bddSHONG Yifan     targets: &[String],
16*d4726bddSHONG Yifan ) -> anyhow::Result<()> {
17*d4726bddSHONG Yifan     log::debug!("Building rust_analyzer_crate_spec files for {:?}", targets);
18*d4726bddSHONG Yifan 
19*d4726bddSHONG Yifan     let output = Command::new(bazel.as_ref())
20*d4726bddSHONG Yifan         .current_dir(workspace.as_ref())
21*d4726bddSHONG Yifan         .env_remove("BAZELISK_SKIP_WRAPPER")
22*d4726bddSHONG Yifan         .env_remove("BUILD_WORKING_DIRECTORY")
23*d4726bddSHONG Yifan         .env_remove("BUILD_WORKSPACE_DIRECTORY")
24*d4726bddSHONG Yifan         .arg("build")
25*d4726bddSHONG Yifan         .arg("--norun_validations")
26*d4726bddSHONG Yifan         .arg(format!(
27*d4726bddSHONG Yifan             "--aspects={}//rust:defs.bzl%rust_analyzer_aspect",
28*d4726bddSHONG Yifan             rules_rust.as_ref()
29*d4726bddSHONG Yifan         ))
30*d4726bddSHONG Yifan         .arg("--output_groups=rust_analyzer_crate_spec,rust_generated_srcs")
31*d4726bddSHONG Yifan         .args(targets)
32*d4726bddSHONG Yifan         .output()?;
33*d4726bddSHONG Yifan 
34*d4726bddSHONG Yifan     if !output.status.success() {
35*d4726bddSHONG Yifan         return Err(anyhow!(
36*d4726bddSHONG Yifan             "bazel build failed:({})\n{}",
37*d4726bddSHONG Yifan             output.status,
38*d4726bddSHONG Yifan             String::from_utf8_lossy(&output.stderr)
39*d4726bddSHONG Yifan         ));
40*d4726bddSHONG Yifan     }
41*d4726bddSHONG Yifan 
42*d4726bddSHONG Yifan     Ok(())
43*d4726bddSHONG Yifan }
44*d4726bddSHONG Yifan 
write_rust_project( bazel: impl AsRef<Path>, workspace: impl AsRef<Path>, rules_rust_name: &impl AsRef<str>, targets: &[String], execution_root: impl AsRef<Path>, output_base: impl AsRef<Path>, rust_project_path: impl AsRef<Path>, ) -> anyhow::Result<()>45*d4726bddSHONG Yifan pub fn write_rust_project(
46*d4726bddSHONG Yifan     bazel: impl AsRef<Path>,
47*d4726bddSHONG Yifan     workspace: impl AsRef<Path>,
48*d4726bddSHONG Yifan     rules_rust_name: &impl AsRef<str>,
49*d4726bddSHONG Yifan     targets: &[String],
50*d4726bddSHONG Yifan     execution_root: impl AsRef<Path>,
51*d4726bddSHONG Yifan     output_base: impl AsRef<Path>,
52*d4726bddSHONG Yifan     rust_project_path: impl AsRef<Path>,
53*d4726bddSHONG Yifan ) -> anyhow::Result<()> {
54*d4726bddSHONG Yifan     let crate_specs = aquery::get_crate_specs(
55*d4726bddSHONG Yifan         bazel.as_ref(),
56*d4726bddSHONG Yifan         workspace.as_ref(),
57*d4726bddSHONG Yifan         execution_root.as_ref(),
58*d4726bddSHONG Yifan         targets,
59*d4726bddSHONG Yifan         rules_rust_name.as_ref(),
60*d4726bddSHONG Yifan     )?;
61*d4726bddSHONG Yifan 
62*d4726bddSHONG Yifan     let path = runfiles::rlocation!(
63*d4726bddSHONG Yifan         Runfiles::create()?,
64*d4726bddSHONG Yifan         "rules_rust/rust/private/rust_analyzer_detect_sysroot.rust_analyzer_toolchain.json"
65*d4726bddSHONG Yifan     );
66*d4726bddSHONG Yifan     let toolchain_info: HashMap<String, String> =
67*d4726bddSHONG Yifan         serde_json::from_str(&std::fs::read_to_string(path)?)?;
68*d4726bddSHONG Yifan 
69*d4726bddSHONG Yifan     let sysroot_src = &toolchain_info["sysroot_src"];
70*d4726bddSHONG Yifan     let sysroot = &toolchain_info["sysroot"];
71*d4726bddSHONG Yifan 
72*d4726bddSHONG Yifan     let rust_project = rust_project::generate_rust_project(sysroot, sysroot_src, &crate_specs)?;
73*d4726bddSHONG Yifan 
74*d4726bddSHONG Yifan     rust_project::write_rust_project(
75*d4726bddSHONG Yifan         rust_project_path.as_ref(),
76*d4726bddSHONG Yifan         execution_root.as_ref(),
77*d4726bddSHONG Yifan         output_base.as_ref(),
78*d4726bddSHONG Yifan         &rust_project,
79*d4726bddSHONG Yifan     )?;
80*d4726bddSHONG Yifan 
81*d4726bddSHONG Yifan     Ok(())
82*d4726bddSHONG Yifan }
83