Skip to content

Commit cd9063c

Browse files
committed
set kebab_case_name on proc-macro builds
Signed-off-by: onur-ozkan <work@onurozkan.dev>
1 parent 9219a80 commit cd9063c

File tree

2 files changed

+43
-21
lines changed

2 files changed

+43
-21
lines changed

src/bootstrap/src/core/build_steps/setup.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ fn create_ra_project_json_maybe(builder: &Builder<'_>) -> io::Result<bool> {
669669

670670
if should_create {
671671
let ra_project = RustAnalyzerProject::collect_ra_project_data(builder);
672-
ra_project.generate_file(&builder.config.src.join("rust-project.json"))?;
672+
ra_project.generate_json_file(&builder.config.src.join("rust-project.json"))?;
673673
println!("Created `rust-project.json`");
674674
}
675675

src/bootstrap/src/utils/ra_project.rs

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@ use crate::core::builder::Builder;
2020
use crate::core::metadata::{project_metadata, workspace_members, Dependency};
2121

2222
#[derive(Debug, Serialize)]
23-
/// FIXME(before-merge): doc-comment
23+
/// Represents the root object in `rust-project.json`
2424
pub(crate) struct RustAnalyzerProject {
2525
crates: Vec<Crate>,
2626
sysroot: String,
2727
sysroot_src: String,
2828
}
2929

30+
/// Represents the crate object in `rust-project.json`
3031
#[derive(Debug, Default, Serialize, PartialEq)]
3132
struct Crate {
3233
cfg: Vec<String>,
@@ -42,13 +43,18 @@ struct Crate {
4243
}
4344

4445
#[derive(Debug, Default, Serialize, PartialEq, PartialOrd, Ord, Eq)]
46+
/// Represents the dependency object in `rust-project.json`
4547
struct Dep {
4648
#[serde(rename = "crate")]
4749
crate_index: usize,
4850
name: String,
4951
}
5052

5153
impl RustAnalyzerProject {
54+
/// Gathers data for `rust-project.json` from `cargo metadata`.
55+
///
56+
/// Skips the indirect dependency crates since we don't need to
57+
/// run LSP on them.
5258
pub(crate) fn collect_ra_project_data(builder: &Builder<'_>) -> Self {
5359
let config = &builder.config;
5460

@@ -61,6 +67,7 @@ impl RustAnalyzerProject {
6167
let packages: Vec<_> = project_metadata(config).collect();
6268
let workspace_members: Vec<_> = workspace_members(config).collect();
6369

70+
// Handle crates in the workspace
6471
for package in &packages {
6572
let is_not_indirect_dependency = packages
6673
.iter()
@@ -105,42 +112,56 @@ impl RustAnalyzerProject {
105112
ra_project.crates.sort_by_key(|c| c.display_name.clone());
106113
ra_project.crates.dedup_by_key(|c| c.display_name.clone());
107114

108-
// Find and fill dependencies of crates.
115+
let mut info_is_printed = false;
116+
117+
// Handle dependencies and proc-macro dylibs
109118
for package in packages {
110119
if let Some(index) =
111120
ra_project.crates.iter().position(|c| c.display_name == package.name)
112121
{
113-
assert!(
114-
!package.manifest_path.is_empty(),
115-
"manifest_path must be valid for proc-macro crates."
116-
);
117-
118-
let mut cargo = Command::new(&builder.initial_cargo);
119-
cargo
120-
.env("RUSTC_BOOTSTRAP", "1")
121-
.arg("build")
122-
.arg("--manifest-path")
123-
.arg(package.manifest_path);
124-
125122
if ra_project.crates[index].is_proc_macro {
126-
// FIXME(before-merge): use `CARGO_TARGET_DIR` to place shared libraries in the build output directory.
123+
let date = &builder.config.stage0_metadata.compiler.date;
124+
125+
let cargo_target_dir = builder
126+
.out
127+
.join("cache")
128+
.join("proc-macro-artifacts-for-ra")
129+
// Although it's rare (when the stage0 compiler changes while proc-macro artifacts under
130+
// `proc-macro-artifacts-for-ra` directory exist), there is a chance of ABI mismatch between
131+
// the stage0 compiler and dynamic libraries. Therefore, we want to trigger compilations
132+
// when the stage0 compiler changes.
133+
.join(format!("{date}_{}", package.name));
134+
135+
let mut cargo = Command::new(&builder.initial_cargo);
136+
cargo
137+
.env("RUSTC_BOOTSTRAP", "1")
138+
.env("CARGO_TARGET_DIR", cargo_target_dir)
139+
.arg("build")
140+
.arg("--manifest-path")
141+
.arg(package.manifest_path);
142+
143+
if !info_is_printed {
144+
builder.info("Building proc-macro artifacts to be used for rust-analyzer");
145+
}
146+
147+
info_is_printed = true;
148+
127149
let ok = stream_cargo(builder, cargo.into(), vec![], &mut |msg| {
128150
let filenames = match msg {
129151
CargoMessage::CompilerArtifact { filenames, .. } => filenames,
130152
_ => return,
131153
};
132154

133155
for filename in filenames {
156+
let kebab_case = &ra_project.crates[index].display_name;
134157
let snake_case_name = ra_project.crates[index]
135158
.display_name
136159
.replace('-', "_")
137160
.to_lowercase();
138161

139162
if filename.ends_with(".so")
140-
&& (filename.contains(&format!(
141-
"lib{}",
142-
ra_project.crates[index].display_name
143-
)) || filename.contains(&format!("lib{}", snake_case_name)))
163+
&& (filename.contains(&format!("lib{}", kebab_case))
164+
|| filename.contains(&format!("lib{}", snake_case_name)))
144165
{
145166
ra_project.crates[index].proc_macro_dylib_path =
146167
Some(filename.to_string());
@@ -173,7 +194,8 @@ impl RustAnalyzerProject {
173194
ra_project
174195
}
175196

176-
pub(crate) fn generate_file(&self, path: &Path) -> io::Result<()> {
197+
/// Generates a json file on the given path.
198+
pub(crate) fn generate_json_file(&self, path: &Path) -> io::Result<()> {
177199
if path.exists() {
178200
return Err(io::Error::new(
179201
io::ErrorKind::AlreadyExists,

0 commit comments

Comments
 (0)