Skip to content

Commit

Permalink
Merge pull request #18867 from Veykril/push-ntmxlropxkrr
Browse files Browse the repository at this point in the history
internal: target-triple -> target-tuple + version fetching cleanup
  • Loading branch information
Veykril authored Jan 7, 2025
2 parents 86d35a5 + 59c8e27 commit 619af18
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 102 deletions.
3 changes: 2 additions & 1 deletion crates/project-model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ pub mod project_json;
pub mod toolchain_info {
pub mod rustc_cfg;
pub mod target_data_layout;
pub mod target_triple;
pub mod target_tuple;
pub mod version;

use std::path::Path;

Expand Down
31 changes: 28 additions & 3 deletions crates/project-model/src/toolchain_info/rustc_cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,11 @@ fn rustc_print_cfg(
QueryConfig::Cargo(sysroot, cargo_toml) => {
let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent());
cmd.envs(extra_env);
cmd.env("RUSTC_BOOTSTRAP", "1");
cmd.args(["rustc", "-Z", "unstable-options"]).args(RUSTC_ARGS);
cmd.args(["--", "-O"]);
cmd.args(["rustc"]).args(RUSTC_ARGS);
if let Some(target) = target {
cmd.args(["--target", target]);
}
cmd.args(["--", "-O"]);

match utf8_stdout(&mut cmd) {
Ok(it) => return Ok(it),
Expand All @@ -97,3 +96,29 @@ fn rustc_print_cfg(

utf8_stdout(&mut cmd).with_context(|| format!("unable to fetch cfgs via `{cmd:?}`"))
}

#[cfg(test)]
mod tests {
use paths::{AbsPathBuf, Utf8PathBuf};

use crate::{ManifestPath, Sysroot};

use super::*;

#[test]
fn cargo() {
let manifest_path = concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml");
let sysroot = Sysroot::empty();
let manifest_path =
ManifestPath::try_from(AbsPathBuf::assert(Utf8PathBuf::from(manifest_path))).unwrap();
let cfg = QueryConfig::Cargo(&sysroot, &manifest_path);
assert_ne!(get(cfg, None, &FxHashMap::default()), vec![]);
}

#[test]
fn rustc() {
let sysroot = Sysroot::empty();
let cfg = QueryConfig::Rustc(&sysroot, env!("CARGO_MANIFEST_DIR").as_ref());
assert_ne!(get(cfg, None, &FxHashMap::default()), vec![]);
}
}
26 changes: 26 additions & 0 deletions crates/project-model/src/toolchain_info/target_data_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,29 @@ pub fn get(
.with_context(|| format!("unable to fetch target-data-layout via `{cmd:?}`"))
.and_then(process)
}

#[cfg(test)]
mod tests {
use paths::{AbsPathBuf, Utf8PathBuf};

use crate::{ManifestPath, Sysroot};

use super::*;

#[test]
fn cargo() {
let manifest_path = concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml");
let sysroot = Sysroot::empty();
let manifest_path =
ManifestPath::try_from(AbsPathBuf::assert(Utf8PathBuf::from(manifest_path))).unwrap();
let cfg = QueryConfig::Cargo(&sysroot, &manifest_path);
assert!(get(cfg, None, &FxHashMap::default()).is_ok());
}

#[test]
fn rustc() {
let sysroot = Sysroot::empty();
let cfg = QueryConfig::Rustc(&sysroot, env!("CARGO_MANIFEST_DIR").as_ref());
assert!(get(cfg, None, &FxHashMap::default()).is_ok());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn get(
target: Option<&str>,
extra_env: &FxHashMap<String, String>,
) -> anyhow::Result<Vec<String>> {
let _p = tracing::info_span!("target_triple::get").entered();
let _p = tracing::info_span!("target_tuple::get").entered();
if let Some(target) = target {
return Ok(vec![target.to_owned()]);
}
Expand All @@ -28,10 +28,10 @@ pub fn get(
}
QueryConfig::Rustc(sysroot, current_dir) => (sysroot, current_dir),
};
rustc_discover_host_triple(extra_env, sysroot, current_dir).map(|it| vec![it])
rustc_discover_host_tuple(extra_env, sysroot, current_dir).map(|it| vec![it])
}

fn rustc_discover_host_triple(
fn rustc_discover_host_tuple(
extra_env: &FxHashMap<String, String>,
sysroot: &Sysroot,
current_dir: &Path,
Expand Down Expand Up @@ -60,14 +60,14 @@ fn cargo_config_build_target(
cmd.envs(extra_env);
cmd.current_dir(cargo_toml.parent()).env("RUSTC_BOOTSTRAP", "1");
cmd.args(["-Z", "unstable-options", "config", "get", "build.target"]);
// if successful we receive `build.target = "target-triple"`
// if successful we receive `build.target = "target-tuple"`
// or `build.target = ["<target 1>", ..]`
// this might be `error: config value `build.target` is not set` in which case we
// don't wanna log the error
utf8_stdout(&mut cmd).and_then(parse_output_cargo_config_build_target).ok()
}

// Parses `"build.target = [target-triple, target-triple, ...]"` or `"build.target = "target-triple"`
// Parses `"build.target = [target-tuple, target-tuple, ...]"` or `"build.target = "target-tuple"`
fn parse_output_cargo_config_build_target(stdout: String) -> anyhow::Result<Vec<String>> {
let trimmed = stdout.trim_start_matches("build.target = ").trim_matches('"');

Expand All @@ -77,3 +77,29 @@ fn parse_output_cargo_config_build_target(stdout: String) -> anyhow::Result<Vec<

serde_json::from_str(trimmed).context("Failed to parse `build.target` as an array of target")
}

#[cfg(test)]
mod tests {
use paths::{AbsPathBuf, Utf8PathBuf};

use crate::{ManifestPath, Sysroot};

use super::*;

#[test]
fn cargo() {
let manifest_path = concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml");
let sysroot = Sysroot::empty();
let manifest_path =
ManifestPath::try_from(AbsPathBuf::assert(Utf8PathBuf::from(manifest_path))).unwrap();
let cfg = QueryConfig::Cargo(&sysroot, &manifest_path);
assert!(get(cfg, None, &FxHashMap::default()).is_ok());
}

#[test]
fn rustc() {
let sysroot = Sysroot::empty();
let cfg = QueryConfig::Rustc(&sysroot, env!("CARGO_MANIFEST_DIR").as_ref());
assert!(get(cfg, None, &FxHashMap::default()).is_ok());
}
}
58 changes: 58 additions & 0 deletions crates/project-model/src/toolchain_info/version.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! Get the version string of the toolchain.
use anyhow::Context;
use rustc_hash::FxHashMap;
use semver::Version;
use toolchain::Tool;

use crate::{toolchain_info::QueryConfig, utf8_stdout};

pub(crate) fn get(
config: QueryConfig<'_>,
extra_env: &FxHashMap<String, String>,
) -> Result<Option<Version>, anyhow::Error> {
let (mut cmd, prefix) = match config {
QueryConfig::Cargo(sysroot, cargo_toml) => {
(sysroot.tool(Tool::Cargo, cargo_toml.parent()), "cargo ")
}
QueryConfig::Rustc(sysroot, current_dir) => {
(sysroot.tool(Tool::Rustc, current_dir), "rustc ")
}
};
cmd.envs(extra_env);
cmd.arg("--version");
let out = utf8_stdout(&mut cmd).with_context(|| format!("Failed to query rust toolchain version via `{cmd:?}`, is your toolchain setup correctly?"))?;

let version =
out.strip_prefix(prefix).and_then(|it| Version::parse(it.split_whitespace().next()?).ok());
if version.is_none() {
tracing::warn!("Failed to parse `{cmd:?}` output `{out}` as a semver version");
}
anyhow::Ok(version)
}

#[cfg(test)]
mod tests {
use paths::{AbsPathBuf, Utf8PathBuf};

use crate::{ManifestPath, Sysroot};

use super::*;

#[test]
fn cargo() {
let manifest_path = concat!(env!("CARGO_MANIFEST_DIR"), "/Cargo.toml");
let sysroot = Sysroot::empty();
let manifest_path =
ManifestPath::try_from(AbsPathBuf::assert(Utf8PathBuf::from(manifest_path))).unwrap();
let cfg = QueryConfig::Cargo(&sysroot, &manifest_path);
assert!(get(cfg, &FxHashMap::default()).is_ok());
}

#[test]
fn rustc() {
let sysroot = Sysroot::empty();
let cfg = QueryConfig::Rustc(&sysroot, env!("CARGO_MANIFEST_DIR").as_ref());
assert!(get(cfg, &FxHashMap::default()).is_ok());
}
}
123 changes: 38 additions & 85 deletions crates/project-model/src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use paths::{AbsPath, AbsPathBuf};
use rustc_hash::FxHashMap;
use semver::Version;
use span::{Edition, FileId};
use toolchain::Tool;
use tracing::instrument;
use triomphe::Arc;

Expand All @@ -26,10 +25,10 @@ use crate::{
env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env},
project_json::{Crate, CrateArrayIdx},
sysroot::{SysrootCrate, SysrootWorkspace},
toolchain_info::{rustc_cfg, target_data_layout, target_triple, QueryConfig},
utf8_stdout, CargoConfig, CargoWorkspace, CfgOverrides, InvocationStrategy, ManifestPath,
Package, ProjectJson, ProjectManifest, Sysroot, SysrootSourceWorkspaceConfig, TargetData,
TargetKind, WorkspaceBuildScripts,
toolchain_info::{rustc_cfg, target_data_layout, target_tuple, version, QueryConfig},
CargoConfig, CargoWorkspace, CfgOverrides, InvocationStrategy, ManifestPath, Package,
ProjectJson, ProjectManifest, Sysroot, SysrootSourceWorkspaceConfig, TargetData, TargetKind,
WorkspaceBuildScripts,
};
use tracing::{debug, error, info};

Expand Down Expand Up @@ -151,27 +150,6 @@ impl fmt::Debug for ProjectWorkspace {
}
}

fn get_toolchain_version(
current_dir: &AbsPath,
sysroot: &Sysroot,
tool: Tool,
extra_env: &FxHashMap<String, String>,
prefix: &str,
) -> Result<Option<Version>, anyhow::Error> {
let cargo_version = utf8_stdout(&mut {
let mut cmd = Sysroot::tool(sysroot, tool, current_dir);
cmd.envs(extra_env);
cmd.arg("--version");
cmd
})
.with_context(|| format!("Failed to query rust toolchain version at {current_dir}, is your toolchain setup correctly?"))?;
anyhow::Ok(
cargo_version
.get(prefix.len()..)
.and_then(|it| Version::parse(it.split_whitespace().next()?).ok()),
)
}

impl ProjectWorkspace {
pub fn load(
manifest: ProjectManifest,
Expand Down Expand Up @@ -242,16 +220,35 @@ impl ProjectWorkspace {
.ok_or_else(|| Some("Failed to discover rustc source for sysroot.".to_owned())),
None => Err(None),
};
let targets = target_triple::get(
QueryConfig::Cargo(&sysroot, cargo_toml),
config.target.as_deref(),

tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = ?sysroot.root(), "Using sysroot");
let toolchain_config = QueryConfig::Cargo(&sysroot, cargo_toml);
let targets =
target_tuple::get(toolchain_config, config.target.as_deref(), &config.extra_env)
.unwrap_or_default();
let toolchain = version::get(toolchain_config, &config.extra_env)
.inspect_err(|e| {
tracing::error!(%e,
"failed fetching toolchain version for {cargo_toml:?} workspace"
)
})
.ok()
.flatten();
let rustc_cfg =
rustc_cfg::get(toolchain_config, targets.first().map(Deref::deref), &config.extra_env);
let cfg_overrides = config.cfg_overrides.clone();
let data_layout = target_data_layout::get(
toolchain_config,
targets.first().map(Deref::deref),
&config.extra_env,
)
.unwrap_or_default();
);
if let Err(e) = &data_layout {
tracing::error!(%e, "failed fetching data layout for {cargo_toml:?} workspace");
}
sysroot.load_workspace(&SysrootSourceWorkspaceConfig::CargoMetadata(
sysroot_metadata_config(&config.extra_env, &targets),
));
tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.src_root(), root = ?sysroot.root(), "Using sysroot");

let rustc = rustc_dir.and_then(|rustc_dir| {
info!(workspace = %cargo_toml, rustc_dir = %rustc_dir, "Using rustc source");
match CargoWorkspace::fetch_metadata(
Expand Down Expand Up @@ -288,27 +285,7 @@ impl ProjectWorkspace {
}
}
});
let toolchain = get_toolchain_version(
cargo_toml.parent(),
&sysroot,
Tool::Cargo,
&config.extra_env,
"cargo ",
)?;
let rustc_cfg = rustc_cfg::get(
QueryConfig::Cargo(&sysroot, cargo_toml),
targets.first().map(Deref::deref),
&config.extra_env,
);
let cfg_overrides = config.cfg_overrides.clone();
let data_layout = target_data_layout::get(
QueryConfig::Cargo(&sysroot, cargo_toml),
targets.first().map(Deref::deref),
&config.extra_env,
);
if let Err(e) = &data_layout {
tracing::error!(%e, "failed fetching data layout for {cargo_toml:?} workspace");
}

let (meta, error) = CargoWorkspace::fetch_metadata(
cargo_toml,
cargo_toml.parent(),
Expand All @@ -329,6 +306,7 @@ impl ProjectWorkspace {
})?;
let cargo_config_extra_env = cargo_config_env(cargo_toml, &config.extra_env, &sysroot);
let cargo = CargoWorkspace::new(meta, cargo_toml.clone(), cargo_config_extra_env);

Ok(ProjectWorkspace {
kind: ProjectWorkspaceKind::Cargo {
cargo,
Expand All @@ -350,19 +328,7 @@ impl ProjectWorkspace {
Sysroot::new(project_json.sysroot.clone(), project_json.sysroot_src.clone());
sysroot.load_workspace(&SysrootSourceWorkspaceConfig::Stitched);
let query_config = QueryConfig::Rustc(&sysroot, project_json.path().as_ref());
let toolchain = match get_toolchain_version(
project_json.path(),
&sysroot,
Tool::Rustc,
&config.extra_env,
"rustc ",
) {
Ok(it) => it,
Err(e) => {
tracing::error!("{e}");
None
}
};
let toolchain = version::get(query_config, &config.extra_env).ok().flatten();

let target = config.target.as_deref();
let rustc_cfg = rustc_cfg::get(query_config, target, &config.extra_env);
Expand All @@ -388,28 +354,15 @@ impl ProjectWorkspace {
None => Sysroot::empty(),
};

let toolchain =
match get_toolchain_version(dir, &sysroot, Tool::Rustc, &config.extra_env, "rustc ") {
Ok(it) => it,
Err(e) => {
tracing::error!("{e}");
None
}
};

let targets = target_triple::get(
QueryConfig::Cargo(&sysroot, detached_file),
config.target.as_deref(),
&config.extra_env,
)
.unwrap_or_default();

let query_config = QueryConfig::Cargo(&sysroot, detached_file);
let toolchain = version::get(query_config, &config.extra_env).ok().flatten();
let targets = target_tuple::get(query_config, config.target.as_deref(), &config.extra_env)
.unwrap_or_default();
let rustc_cfg = rustc_cfg::get(query_config, None, &config.extra_env);
let data_layout = target_data_layout::get(query_config, None, &config.extra_env);
sysroot.load_workspace(&SysrootSourceWorkspaceConfig::CargoMetadata(
sysroot_metadata_config(&config.extra_env, &targets),
));
let query_config = QueryConfig::Rustc(&sysroot, dir.as_ref());
let rustc_cfg = rustc_cfg::get(query_config, None, &config.extra_env);
let data_layout = target_data_layout::get(query_config, None, &config.extra_env);

let cargo_script = CargoWorkspace::fetch_metadata(
detached_file,
Expand Down
Loading

0 comments on commit 619af18

Please sign in to comment.