Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/project-model/src/toolchain_info/target_tuple.rs')
| -rw-r--r-- | crates/project-model/src/toolchain_info/target_tuple.rs | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/crates/project-model/src/toolchain_info/target_tuple.rs b/crates/project-model/src/toolchain_info/target_tuple.rs index f6ab853219..9f12ededb6 100644 --- a/crates/project-model/src/toolchain_info/target_tuple.rs +++ b/crates/project-model/src/toolchain_info/target_tuple.rs @@ -5,7 +5,9 @@ use anyhow::Context; use rustc_hash::FxHashMap; use toolchain::Tool; -use crate::{ManifestPath, Sysroot, toolchain_info::QueryConfig, utf8_stdout}; +use crate::{ + Sysroot, cargo_config_file::CargoConfigFile, toolchain_info::QueryConfig, utf8_stdout, +}; /// For cargo, runs `cargo -Zunstable-options config get build.target` to get the configured project target(s). /// For rustc, runs `rustc --print -vV` to get the host target. @@ -20,8 +22,8 @@ pub fn get( } let (sysroot, current_dir) = match config { - QueryConfig::Cargo(sysroot, cargo_toml) => { - match cargo_config_build_target(cargo_toml, extra_env, sysroot) { + QueryConfig::Cargo(sysroot, cargo_toml, config_file) => { + match config_file.as_ref().and_then(cargo_config_build_target) { Some(it) => return Ok(it), None => (sysroot, cargo_toml.parent().as_ref()), } @@ -50,30 +52,30 @@ fn rustc_discover_host_tuple( } } -fn cargo_config_build_target( - cargo_toml: &ManifestPath, - extra_env: &FxHashMap<String, Option<String>>, - sysroot: &Sysroot, -) -> Option<Vec<String>> { - let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent(), 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-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() +fn cargo_config_build_target(config: &CargoConfigFile) -> Option<Vec<String>> { + match parse_json_cargo_config_build_target(config) { + Ok(v) => v, + Err(e) => { + tracing::debug!("Failed to discover cargo config build target {e:?}"); + None + } + } } // 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('"'); - - if !trimmed.starts_with('[') { - return Ok([trimmed.to_owned()].to_vec()); +fn parse_json_cargo_config_build_target( + config: &CargoConfigFile, +) -> anyhow::Result<Option<Vec<String>>> { + let target = config.get("build").and_then(|v| v.as_object()).and_then(|m| m.get("target")); + match target { + Some(serde_json::Value::String(s)) => Ok(Some(vec![s.to_owned()])), + Some(v) => serde_json::from_value(v.clone()) + .map(Option::Some) + .context("Failed to parse `build.target` as an array of target"), + // t`error: config value `build.target` is not set`, in which case we + // don't wanna log the error + None => Ok(None), } - - serde_json::from_str(trimmed).context("Failed to parse `build.target` as an array of target") } #[cfg(test)] @@ -90,7 +92,7 @@ mod tests { let sysroot = Sysroot::empty(); let manifest_path = ManifestPath::try_from(AbsPathBuf::assert(Utf8PathBuf::from(manifest_path))).unwrap(); - let cfg = QueryConfig::Cargo(&sysroot, &manifest_path); + let cfg = QueryConfig::Cargo(&sysroot, &manifest_path, &None); assert!(get(cfg, None, &FxHashMap::default()).is_ok()); } |