Load proc-macros for rustc_private crates
This commit is contained in:
parent
ecc32c2f85
commit
c9786484c5
@ -15,13 +15,13 @@ use std::{
|
|||||||
|
|
||||||
use cargo_metadata::{camino::Utf8Path, Message};
|
use cargo_metadata::{camino::Utf8Path, Message};
|
||||||
use la_arena::ArenaMap;
|
use la_arena::ArenaMap;
|
||||||
use paths::AbsPathBuf;
|
use paths::{AbsPath, AbsPathBuf};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cfg_flag::CfgFlag, CargoConfig, CargoFeatures, CargoWorkspace, InvocationLocation,
|
cfg_flag::CfgFlag, utf8_stdout, CargoConfig, CargoFeatures, CargoWorkspace, InvocationLocation,
|
||||||
InvocationStrategy, Package,
|
InvocationStrategy, Package,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -250,7 +250,7 @@ impl WorkspaceBuildScripts {
|
|||||||
|
|
||||||
if tracing::enabled!(tracing::Level::INFO) {
|
if tracing::enabled!(tracing::Level::INFO) {
|
||||||
for package in workspace.packages() {
|
for package in workspace.packages() {
|
||||||
let package_build_data = &mut outputs[package];
|
let package_build_data = &outputs[package];
|
||||||
if !package_build_data.is_unchanged() {
|
if !package_build_data.is_unchanged() {
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
"{}: {:?}",
|
"{}: {:?}",
|
||||||
@ -378,6 +378,80 @@ impl WorkspaceBuildScripts {
|
|||||||
pub(crate) fn get_output(&self, idx: Package) -> Option<&BuildScriptOutput> {
|
pub(crate) fn get_output(&self, idx: Package) -> Option<&BuildScriptOutput> {
|
||||||
self.outputs.get(idx)
|
self.outputs.get(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn rustc_crates(
|
||||||
|
rustc: &CargoWorkspace,
|
||||||
|
current_dir: &AbsPath,
|
||||||
|
extra_env: &FxHashMap<String, String>,
|
||||||
|
) -> Self {
|
||||||
|
let mut bs = WorkspaceBuildScripts::default();
|
||||||
|
for p in rustc.packages() {
|
||||||
|
bs.outputs.insert(p, BuildScriptOutput::default());
|
||||||
|
}
|
||||||
|
let res = (|| {
|
||||||
|
let target_libdir = (|| {
|
||||||
|
let mut cargo_config = Command::new(toolchain::cargo());
|
||||||
|
cargo_config.envs(extra_env);
|
||||||
|
cargo_config
|
||||||
|
.current_dir(current_dir)
|
||||||
|
.args(["rustc", "-Z", "unstable-options", "--print", "target-libdir"])
|
||||||
|
.env("RUSTC_BOOTSTRAP", "1");
|
||||||
|
if let Ok(it) = utf8_stdout(cargo_config) {
|
||||||
|
return Ok(it);
|
||||||
|
}
|
||||||
|
let mut cmd = Command::new(toolchain::rustc());
|
||||||
|
cmd.envs(extra_env);
|
||||||
|
cmd.args(["--print", "target-libdir"]);
|
||||||
|
utf8_stdout(cmd)
|
||||||
|
})()?;
|
||||||
|
|
||||||
|
let target_libdir = AbsPathBuf::try_from(PathBuf::from(target_libdir))
|
||||||
|
.map_err(|_| anyhow::format_err!("target-libdir was not an absolute path"))?;
|
||||||
|
tracing::info!("Loading rustc proc-macro paths from {}", target_libdir.display());
|
||||||
|
|
||||||
|
let proc_macro_dylibs: Vec<(String, AbsPathBuf)> = std::fs::read_dir(target_libdir)?
|
||||||
|
.filter_map(|entry| {
|
||||||
|
let dir_entry = entry.ok()?;
|
||||||
|
if dir_entry.file_type().ok()?.is_file() {
|
||||||
|
let path = dir_entry.path();
|
||||||
|
tracing::info!("p{:?}", path);
|
||||||
|
let extension = path.extension()?;
|
||||||
|
if extension == "dll" || extension == "so" {
|
||||||
|
let name = path.file_stem()?.to_str()?.split_once('-')?.0.to_owned();
|
||||||
|
let path = AbsPathBuf::try_from(path).ok()?;
|
||||||
|
return Some((name, path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
for p in rustc.packages() {
|
||||||
|
if let Some((_, path)) =
|
||||||
|
proc_macro_dylibs.iter().find(|(name, _)| *name == rustc[p].name)
|
||||||
|
{
|
||||||
|
bs.outputs[p].proc_macro_dylib_path = Some(path.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tracing::enabled!(tracing::Level::INFO) {
|
||||||
|
for package in rustc.packages() {
|
||||||
|
let package_build_data = &bs.outputs[package];
|
||||||
|
if !package_build_data.is_unchanged() {
|
||||||
|
tracing::info!(
|
||||||
|
"{}: {:?}",
|
||||||
|
rustc[package].manifest.parent().display(),
|
||||||
|
package_build_data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})();
|
||||||
|
if let Err::<_, anyhow::Error>(e) = res {
|
||||||
|
bs.error = Some(e.to_string());
|
||||||
|
}
|
||||||
|
bs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Find a better way to know if it is a dylib.
|
// FIXME: Find a better way to know if it is a dylib.
|
||||||
|
@ -88,23 +88,17 @@ impl Sysroot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn discover_with_src_override(
|
pub fn discover_with_src_override(
|
||||||
dir: &AbsPath,
|
current_dir: &AbsPath,
|
||||||
extra_env: &FxHashMap<String, String>,
|
extra_env: &FxHashMap<String, String>,
|
||||||
src: AbsPathBuf,
|
src: AbsPathBuf,
|
||||||
) -> Result<Sysroot> {
|
) -> Result<Sysroot> {
|
||||||
tracing::debug!("discovering sysroot for {}", dir.display());
|
tracing::debug!("discovering sysroot for {}", current_dir.display());
|
||||||
let sysroot_dir = discover_sysroot_dir(dir, extra_env)?;
|
let sysroot_dir = discover_sysroot_dir(current_dir, extra_env)?;
|
||||||
Ok(Sysroot::load(sysroot_dir, src))
|
Ok(Sysroot::load(sysroot_dir, src))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn discover_rustc(
|
pub fn discover_rustc(&self) -> Option<ManifestPath> {
|
||||||
cargo_toml: &ManifestPath,
|
get_rustc_src(&self.root)
|
||||||
extra_env: &FxHashMap<String, String>,
|
|
||||||
) -> Option<ManifestPath> {
|
|
||||||
tracing::debug!("discovering rustc source for {}", cargo_toml.display());
|
|
||||||
let current_dir = cargo_toml.parent();
|
|
||||||
let sysroot_dir = discover_sysroot_dir(current_dir, extra_env).ok()?;
|
|
||||||
get_rustc_src(&sysroot_dir)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_sysroot_dir(sysroot_dir: AbsPathBuf) -> Result<Sysroot> {
|
pub fn with_sysroot_dir(sysroot_dir: AbsPathBuf) -> Result<Sysroot> {
|
||||||
|
@ -70,7 +70,7 @@ pub enum ProjectWorkspace {
|
|||||||
cargo: CargoWorkspace,
|
cargo: CargoWorkspace,
|
||||||
build_scripts: WorkspaceBuildScripts,
|
build_scripts: WorkspaceBuildScripts,
|
||||||
sysroot: Option<Sysroot>,
|
sysroot: Option<Sysroot>,
|
||||||
rustc: Option<CargoWorkspace>,
|
rustc: Option<(CargoWorkspace, WorkspaceBuildScripts)>,
|
||||||
/// Holds cfg flags for the current target. We get those by running
|
/// Holds cfg flags for the current target. We get those by running
|
||||||
/// `rustc --print cfg`.
|
/// `rustc --print cfg`.
|
||||||
///
|
///
|
||||||
@ -116,7 +116,7 @@ impl fmt::Debug for ProjectWorkspace {
|
|||||||
.field("sysroot", &sysroot.is_some())
|
.field("sysroot", &sysroot.is_some())
|
||||||
.field(
|
.field(
|
||||||
"n_rustc_compiler_crates",
|
"n_rustc_compiler_crates",
|
||||||
&rustc.as_ref().map_or(0, |rc| rc.packages().len()),
|
&rustc.as_ref().map_or(0, |(rc, _)| rc.packages().len()),
|
||||||
)
|
)
|
||||||
.field("n_rustc_cfg", &rustc_cfg.len())
|
.field("n_rustc_cfg", &rustc_cfg.len())
|
||||||
.field("n_cfg_overrides", &cfg_overrides.len())
|
.field("n_cfg_overrides", &cfg_overrides.len())
|
||||||
@ -243,7 +243,7 @@ impl ProjectWorkspace {
|
|||||||
let rustc_dir = match &config.rustc_source {
|
let rustc_dir = match &config.rustc_source {
|
||||||
Some(RustcSource::Path(path)) => ManifestPath::try_from(path.clone()).ok(),
|
Some(RustcSource::Path(path)) => ManifestPath::try_from(path.clone()).ok(),
|
||||||
Some(RustcSource::Discover) => {
|
Some(RustcSource::Discover) => {
|
||||||
Sysroot::discover_rustc(&cargo_toml, &config.extra_env)
|
sysroot.as_ref().and_then(Sysroot::discover_rustc)
|
||||||
}
|
}
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
@ -257,7 +257,15 @@ impl ProjectWorkspace {
|
|||||||
config,
|
config,
|
||||||
progress,
|
progress,
|
||||||
) {
|
) {
|
||||||
Ok(meta) => Some(CargoWorkspace::new(meta)),
|
Ok(meta) => {
|
||||||
|
let workspace = CargoWorkspace::new(meta);
|
||||||
|
let buildscripts = WorkspaceBuildScripts::rustc_crates(
|
||||||
|
&workspace,
|
||||||
|
cargo_toml.parent(),
|
||||||
|
&config.extra_env,
|
||||||
|
);
|
||||||
|
Some((workspace, buildscripts))
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!(
|
tracing::error!(
|
||||||
%e,
|
%e,
|
||||||
@ -531,7 +539,7 @@ impl ProjectWorkspace {
|
|||||||
PackageRoot { is_local, include, exclude }
|
PackageRoot { is_local, include, exclude }
|
||||||
})
|
})
|
||||||
.chain(mk_sysroot(sysroot.as_ref(), Some(cargo.workspace_root())))
|
.chain(mk_sysroot(sysroot.as_ref(), Some(cargo.workspace_root())))
|
||||||
.chain(rustc.iter().flat_map(|rustc| {
|
.chain(rustc.iter().flat_map(|(rustc, _)| {
|
||||||
rustc.packages().map(move |krate| PackageRoot {
|
rustc.packages().map(move |krate| PackageRoot {
|
||||||
is_local: false,
|
is_local: false,
|
||||||
include: vec![rustc[krate].manifest.parent().to_path_buf()],
|
include: vec![rustc[krate].manifest.parent().to_path_buf()],
|
||||||
@ -559,7 +567,7 @@ impl ProjectWorkspace {
|
|||||||
sysroot_package_len + project.n_crates()
|
sysroot_package_len + project.n_crates()
|
||||||
}
|
}
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot, rustc, .. } => {
|
ProjectWorkspace::Cargo { cargo, sysroot, rustc, .. } => {
|
||||||
let rustc_package_len = rustc.as_ref().map_or(0, |it| it.packages().len());
|
let rustc_package_len = rustc.as_ref().map_or(0, |(it, _)| it.packages().len());
|
||||||
let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.crates().len());
|
let sysroot_package_len = sysroot.as_ref().map_or(0, |it| it.crates().len());
|
||||||
cargo.packages().len() + sysroot_package_len + rustc_package_len
|
cargo.packages().len() + sysroot_package_len + rustc_package_len
|
||||||
}
|
}
|
||||||
@ -778,7 +786,7 @@ fn project_json_to_crate_graph(
|
|||||||
fn cargo_to_crate_graph(
|
fn cargo_to_crate_graph(
|
||||||
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
|
load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
rustc: &Option<CargoWorkspace>,
|
rustc: &Option<(CargoWorkspace, WorkspaceBuildScripts)>,
|
||||||
cargo: &CargoWorkspace,
|
cargo: &CargoWorkspace,
|
||||||
sysroot: Option<&Sysroot>,
|
sysroot: Option<&Sysroot>,
|
||||||
rustc_cfg: Vec<CfgFlag>,
|
rustc_cfg: Vec<CfgFlag>,
|
||||||
@ -924,7 +932,7 @@ fn cargo_to_crate_graph(
|
|||||||
if has_private {
|
if has_private {
|
||||||
// If the user provided a path to rustc sources, we add all the rustc_private crates
|
// If the user provided a path to rustc sources, we add all the rustc_private crates
|
||||||
// and create dependencies on them for the crates which opt-in to that
|
// and create dependencies on them for the crates which opt-in to that
|
||||||
if let Some(rustc_workspace) = rustc {
|
if let Some((rustc_workspace, build_scripts)) = rustc {
|
||||||
handle_rustc_crates(
|
handle_rustc_crates(
|
||||||
&mut crate_graph,
|
&mut crate_graph,
|
||||||
&mut pkg_to_lib_crate,
|
&mut pkg_to_lib_crate,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user