Skip to content

Commit 9219a80

Browse files
committed
compile proc-macro crates and fill dylibs for ra
Signed-off-by: onur-ozkan <work@onurozkan.dev>
1 parent 8bbdb07 commit 9219a80

File tree

3 files changed

+68
-23
lines changed

3 files changed

+68
-23
lines changed

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -648,16 +648,15 @@ impl Step for RustProjectJson {
648648
}
649649
}
650650
fn run(self, builder: &Builder<'_>) -> Self::Output {
651-
let config = &builder.config;
652-
if config.dry_run() {
651+
if builder.config.dry_run() {
653652
return;
654653
}
655654

656-
while !t!(create_ra_project_json_maybe(&config)) {}
655+
while !t!(create_ra_project_json_maybe(builder)) {}
657656
}
658657
}
659658

660-
fn create_ra_project_json_maybe(config: &Config) -> io::Result<bool> {
659+
fn create_ra_project_json_maybe(builder: &Builder<'_>) -> io::Result<bool> {
661660
println!("\nx.py can automatically generate `rust-project.json` file for rust-analyzer");
662661

663662
let should_create = match prompt_user("Would you like to create rust-project.json?: [y/N]")? {
@@ -669,8 +668,8 @@ fn create_ra_project_json_maybe(config: &Config) -> io::Result<bool> {
669668
};
670669

671670
if should_create {
672-
let ra_project = RustAnalyzerProject::collect_ra_project_data(&config);
673-
ra_project.generate_file(&config.src.join("rust-project.json"))?;
671+
let ra_project = RustAnalyzerProject::collect_ra_project_data(builder);
672+
ra_project.generate_file(&builder.config.src.join("rust-project.json"))?;
674673
println!("Created `rust-project.json`");
675674
}
676675

src/bootstrap/src/core/builder.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2274,7 +2274,7 @@ impl<'a> Builder<'a> {
22742274
///
22752275
/// `-Z crate-attr` flags will be applied recursively on the target code using the `rustc_parse::parser::Parser`.
22762276
/// See `rustc_builtin_macros::cmdline_attrs::inject` for more information.
2277-
#[derive(Debug, Clone)]
2277+
#[derive(Debug, Default, Clone)]
22782278
struct Rustflags(String, TargetSelection);
22792279

22802280
impl Rustflags {
@@ -2429,3 +2429,15 @@ impl From<Cargo> for Command {
24292429
cargo.command
24302430
}
24312431
}
2432+
2433+
impl From<Command> for Cargo {
2434+
fn from(command: Command) -> Cargo {
2435+
Cargo {
2436+
command,
2437+
rustflags: Default::default(),
2438+
rustdocflags: Default::default(),
2439+
hostflags: Default::default(),
2440+
allow_features: Default::default(),
2441+
}
2442+
}
2443+
}

src/bootstrap/src/utils/ra_project.rs

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ use serde_derive::Serialize;
1313
use std::collections::{BTreeMap, BTreeSet};
1414
use std::io;
1515
use std::path::Path;
16+
use std::process::Command;
1617

18+
use crate::core::build_steps::compile::{stream_cargo, CargoMessage};
19+
use crate::core::builder::Builder;
1720
use crate::core::metadata::{project_metadata, workspace_members, Dependency};
18-
use crate::Config;
1921

2022
#[derive(Debug, Serialize)]
2123
/// FIXME(before-merge): doc-comment
@@ -47,8 +49,9 @@ struct Dep {
4749
}
4850

4951
impl RustAnalyzerProject {
50-
#[allow(dead_code)] // FIXME(before-merge): remove this
51-
pub(crate) fn collect_ra_project_data(config: &Config) -> Self {
52+
pub(crate) fn collect_ra_project_data(builder: &Builder<'_>) -> Self {
53+
let config = &builder.config;
54+
5255
let mut ra_project = RustAnalyzerProject {
5356
crates: vec![],
5457
sysroot: format!("{}", config.out.join("host").join("stage0").display()),
@@ -86,11 +89,6 @@ impl RustAnalyzerProject {
8689
krate.is_workspace_member = workspace_members.iter().any(|p| p.name == target.name);
8790
krate.is_proc_macro = target.crate_types.contains(&"proc-macro".to_string());
8891

89-
// FIXME(before-merge): We need to figure out how to find proc-macro dylibs.
90-
// if krate.is_proc_macro {
91-
// krate.proc_macro_dylib_path =
92-
// }
93-
9492
krate.env.insert("RUSTC_BOOTSTRAP".into(), "1".into());
9593

9694
if target
@@ -109,14 +107,51 @@ impl RustAnalyzerProject {
109107

110108
// Find and fill dependencies of crates.
111109
for package in packages {
112-
if package.dependencies.is_empty() {
113-
continue;
114-
}
110+
if let Some(index) =
111+
ra_project.crates.iter().position(|c| c.display_name == package.name)
112+
{
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+
125+
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.
127+
let ok = stream_cargo(builder, cargo.into(), vec![], &mut |msg| {
128+
let filenames = match msg {
129+
CargoMessage::CompilerArtifact { filenames, .. } => filenames,
130+
_ => return,
131+
};
132+
133+
for filename in filenames {
134+
let snake_case_name = ra_project.crates[index]
135+
.display_name
136+
.replace('-', "_")
137+
.to_lowercase();
138+
139+
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)))
144+
{
145+
ra_project.crates[index].proc_macro_dylib_path =
146+
Some(filename.to_string());
147+
}
148+
}
149+
});
115150

116-
for dependency in package.dependencies {
117-
if let Some(index) =
118-
ra_project.crates.iter().position(|c| c.display_name == package.name)
119-
{
151+
assert!(ok);
152+
}
153+
154+
for dependency in package.dependencies {
120155
if let Some(dependency_index) =
121156
ra_project.crates.iter().position(|c| c.display_name == dependency.name)
122157
{
@@ -138,7 +173,6 @@ impl RustAnalyzerProject {
138173
ra_project
139174
}
140175

141-
#[allow(dead_code)] // FIXME(before-merge): remove this
142176
pub(crate) fn generate_file(&self, path: &Path) -> io::Result<()> {
143177
if path.exists() {
144178
return Err(io::Error::new(

0 commit comments

Comments
 (0)