Merge pull request #18867 from Veykril/push-ntmxlropxkrr
internal: target-triple -> target-tuple + version fetching cleanup
This commit is contained in:
commit
21faec1fec
11 changed files with 191 additions and 102 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
@ -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![]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()]);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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('"');
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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(),
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
|
|
@ -600,7 +600,7 @@ config_data! {
|
|||
///
|
||||
/// This option does not take effect until rust-analyzer is restarted.
|
||||
cargo_sysrootSrc: Option<String> = None,
|
||||
/// Compilation target override (target triple).
|
||||
/// Compilation target override (target tuple).
|
||||
// FIXME(@poliorcetics): move to multiple targets here too, but this will need more work
|
||||
// than `checkOnSave_target`
|
||||
cargo_target: Option<String> = None,
|
||||
|
@ -2041,7 +2041,7 @@ impl Config {
|
|||
|
||||
pub(crate) fn cargo_test_options(&self, source_root: Option<SourceRootId>) -> CargoOptions {
|
||||
CargoOptions {
|
||||
target_triples: self.cargo_target(source_root).clone().into_iter().collect(),
|
||||
target_tuples: self.cargo_target(source_root).clone().into_iter().collect(),
|
||||
all_targets: false,
|
||||
no_default_features: *self.cargo_noDefaultFeatures(source_root),
|
||||
all_features: matches!(self.cargo_features(source_root), CargoFeaturesDef::All),
|
||||
|
@ -2076,7 +2076,7 @@ impl Config {
|
|||
Some(_) | None => FlycheckConfig::CargoCommand {
|
||||
command: self.check_command(source_root).clone(),
|
||||
options: CargoOptions {
|
||||
target_triples: self
|
||||
target_tuples: self
|
||||
.check_targets(source_root)
|
||||
.clone()
|
||||
.and_then(|targets| match &targets.0[..] {
|
||||
|
|
|
@ -28,7 +28,7 @@ pub(crate) enum InvocationStrategy {
|
|||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub(crate) struct CargoOptions {
|
||||
pub(crate) target_triples: Vec<String>,
|
||||
pub(crate) target_tuples: Vec<String>,
|
||||
pub(crate) all_targets: bool,
|
||||
pub(crate) no_default_features: bool,
|
||||
pub(crate) all_features: bool,
|
||||
|
@ -49,7 +49,7 @@ pub(crate) enum Target {
|
|||
|
||||
impl CargoOptions {
|
||||
pub(crate) fn apply_on_command(&self, cmd: &mut Command) {
|
||||
for target in &self.target_triples {
|
||||
for target in &self.target_tuples {
|
||||
cmd.args(["--target", target.as_str()]);
|
||||
}
|
||||
if self.all_targets {
|
||||
|
|
|
@ -146,7 +146,7 @@ This option does not take effect until rust-analyzer is restarted.
|
|||
[[rust-analyzer.cargo.target]]rust-analyzer.cargo.target (default: `null`)::
|
||||
+
|
||||
--
|
||||
Compilation target override (target triple).
|
||||
Compilation target override (target tuple).
|
||||
--
|
||||
[[rust-analyzer.cargo.targetDir]]rust-analyzer.cargo.targetDir (default: `null`)::
|
||||
+
|
||||
|
|
|
@ -769,7 +769,7 @@ interface Crate {
|
|||
/// The set of cfgs activated for a given crate, like
|
||||
/// `["unix", "feature=\"foo\"", "feature=\"bar\""]`.
|
||||
cfg: string[];
|
||||
/// Target triple for this Crate.
|
||||
/// Target tuple for this Crate.
|
||||
///
|
||||
/// Used when running `rustc --print cfg`
|
||||
/// to get target-specific cfgs.
|
||||
|
|
|
@ -888,7 +888,7 @@
|
|||
"title": "cargo",
|
||||
"properties": {
|
||||
"rust-analyzer.cargo.target": {
|
||||
"markdownDescription": "Compilation target override (target triple).",
|
||||
"markdownDescription": "Compilation target override (target tuple).",
|
||||
"default": null,
|
||||
"type": [
|
||||
"null",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue