mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-27 18:26:19 +00:00
chore: Cleanup cargo config queries
This commit is contained in:
parent
4ddf2f26b4
commit
8dad658bea
8 changed files with 152 additions and 134 deletions
34
crates/project-model/src/cargo_config_file.rs
Normal file
34
crates/project-model/src/cargo_config_file.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
//! Read `.cargo/config.toml` as a JSON object
|
||||
use rustc_hash::FxHashMap;
|
||||
use toolchain::Tool;
|
||||
|
||||
use crate::{ManifestPath, Sysroot, utf8_stdout};
|
||||
|
||||
pub(crate) type CargoConfigFile = serde_json::Map<String, serde_json::Value>;
|
||||
|
||||
pub(crate) fn read(
|
||||
manifest: &ManifestPath,
|
||||
extra_env: &FxHashMap<String, Option<String>>,
|
||||
sysroot: &Sysroot,
|
||||
) -> Option<CargoConfigFile> {
|
||||
let mut cargo_config = sysroot.tool(Tool::Cargo, manifest.parent(), extra_env);
|
||||
cargo_config
|
||||
.args(["-Z", "unstable-options", "config", "get", "--format", "json"])
|
||||
.env("RUSTC_BOOTSTRAP", "1");
|
||||
if manifest.is_rust_manifest() {
|
||||
cargo_config.arg("-Zscript");
|
||||
}
|
||||
|
||||
tracing::debug!("Discovering cargo config by {:?}", cargo_config);
|
||||
let json: serde_json::Map<String, serde_json::Value> = utf8_stdout(&mut cargo_config)
|
||||
.inspect(|json| {
|
||||
tracing::debug!("Discovered cargo config: {:?}", json);
|
||||
})
|
||||
.inspect_err(|err| {
|
||||
tracing::debug!("Failed to discover cargo config: {:?}", err);
|
||||
})
|
||||
.ok()
|
||||
.and_then(|stdout| serde_json::from_str(&stdout).ok())?;
|
||||
|
||||
Some(json)
|
||||
}
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
//! Cargo-like environment variables injection.
|
||||
use base_db::Env;
|
||||
use paths::{Utf8Path, Utf8PathBuf};
|
||||
use rustc_hash::FxHashMap;
|
||||
use paths::Utf8Path;
|
||||
use toolchain::Tool;
|
||||
|
||||
use crate::{ManifestPath, PackageData, Sysroot, TargetKind, utf8_stdout};
|
||||
use crate::{ManifestPath, PackageData, TargetKind, cargo_config_file::CargoConfigFile};
|
||||
|
||||
/// Recreates the compile-time environment variables that Cargo sets.
|
||||
///
|
||||
|
|
@ -61,104 +60,68 @@ pub(crate) fn inject_rustc_tool_env(env: &mut Env, cargo_name: &str, kind: Targe
|
|||
env.set("CARGO_CRATE_NAME", cargo_name.replace('-', "_"));
|
||||
}
|
||||
|
||||
pub(crate) fn cargo_config_env(
|
||||
manifest: &ManifestPath,
|
||||
extra_env: &FxHashMap<String, Option<String>>,
|
||||
sysroot: &Sysroot,
|
||||
) -> Env {
|
||||
let mut cargo_config = sysroot.tool(Tool::Cargo, manifest.parent(), extra_env);
|
||||
cargo_config
|
||||
.args(["-Z", "unstable-options", "config", "get", "env"])
|
||||
.env("RUSTC_BOOTSTRAP", "1");
|
||||
if manifest.is_rust_manifest() {
|
||||
cargo_config.arg("-Zscript");
|
||||
}
|
||||
// if successful we receive `env.key.value = "value" per entry
|
||||
tracing::debug!("Discovering cargo config env by {:?}", cargo_config);
|
||||
utf8_stdout(&mut cargo_config)
|
||||
.map(|stdout| parse_output_cargo_config_env(manifest, &stdout))
|
||||
.inspect(|env| {
|
||||
tracing::debug!("Discovered cargo config env: {:?}", env);
|
||||
})
|
||||
.inspect_err(|err| {
|
||||
tracing::debug!("Failed to discover cargo config env: {:?}", err);
|
||||
})
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn parse_output_cargo_config_env(manifest: &ManifestPath, stdout: &str) -> Env {
|
||||
pub(crate) fn cargo_config_env(manifest: &ManifestPath, config: &Option<CargoConfigFile>) -> Env {
|
||||
let mut env = Env::default();
|
||||
let mut relatives = vec![];
|
||||
for (key, val) in
|
||||
stdout.lines().filter_map(|l| l.strip_prefix("env.")).filter_map(|l| l.split_once(" = "))
|
||||
{
|
||||
let val = val.trim_matches('"').to_owned();
|
||||
if let Some((key, modifier)) = key.split_once('.') {
|
||||
match modifier {
|
||||
"relative" => relatives.push((key, val)),
|
||||
"value" => _ = env.insert(key, val),
|
||||
_ => {
|
||||
tracing::warn!(
|
||||
"Unknown modifier in cargo config env: {}, expected `relative` or `value`",
|
||||
modifier
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
env.insert(key, val);
|
||||
}
|
||||
}
|
||||
let Some(serde_json::Value::Object(env_json)) = config.as_ref().and_then(|c| c.get("env"))
|
||||
else {
|
||||
return env;
|
||||
};
|
||||
|
||||
// FIXME: The base here should be the parent of the `.cargo/config` file, not the manifest.
|
||||
// But cargo does not provide this information.
|
||||
let base = <_ as AsRef<Utf8Path>>::as_ref(manifest.parent());
|
||||
for (key, relative) in relatives {
|
||||
if relative != "true" {
|
||||
continue;
|
||||
}
|
||||
if let Some(suffix) = env.get(key) {
|
||||
env.insert(key, base.join(suffix).to_string());
|
||||
}
|
||||
}
|
||||
env
|
||||
}
|
||||
|
||||
pub(crate) fn cargo_config_build_target_dir(
|
||||
manifest: &ManifestPath,
|
||||
extra_env: &FxHashMap<String, Option<String>>,
|
||||
sysroot: &Sysroot,
|
||||
) -> Option<Utf8PathBuf> {
|
||||
let mut cargo_config = sysroot.tool(Tool::Cargo, manifest.parent(), extra_env);
|
||||
cargo_config
|
||||
.args(["-Z", "unstable-options", "config", "get", "build.target-dir"])
|
||||
.env("RUSTC_BOOTSTRAP", "1");
|
||||
if manifest.is_rust_manifest() {
|
||||
cargo_config.arg("-Zscript");
|
||||
for (key, entry) in env_json {
|
||||
let serde_json::Value::Object(entry) = entry else {
|
||||
continue;
|
||||
};
|
||||
let Some(value) = entry.get("value").and_then(|v| v.as_str()) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let value = if entry
|
||||
.get("relative")
|
||||
.and_then(|v| v.as_bool())
|
||||
.is_some_and(std::convert::identity)
|
||||
{
|
||||
base.join(value).to_string()
|
||||
} else {
|
||||
value.to_owned()
|
||||
};
|
||||
env.insert(key, value);
|
||||
}
|
||||
utf8_stdout(&mut cargo_config)
|
||||
.map(|stdout| {
|
||||
Utf8Path::new(stdout.trim_start_matches("build.target-dir = ").trim_matches('"'))
|
||||
.to_owned()
|
||||
})
|
||||
.ok()
|
||||
|
||||
env
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_output_cargo_config_env_works() {
|
||||
let stdout = r#"
|
||||
env.CARGO_WORKSPACE_DIR.relative = true
|
||||
env.CARGO_WORKSPACE_DIR.value = ""
|
||||
env.RELATIVE.relative = true
|
||||
env.RELATIVE.value = "../relative"
|
||||
env.INVALID.relative = invalidbool
|
||||
env.INVALID.value = "../relative"
|
||||
env.TEST.value = "test"
|
||||
"#
|
||||
.trim();
|
||||
let raw = r#"
|
||||
{
|
||||
"env": {
|
||||
"CARGO_WORKSPACE_DIR": {
|
||||
"relative": true,
|
||||
"value": ""
|
||||
},
|
||||
"INVALID": {
|
||||
"relative": "invalidbool",
|
||||
"value": "../relative"
|
||||
},
|
||||
"RELATIVE": {
|
||||
"relative": true,
|
||||
"value": "../relative"
|
||||
},
|
||||
"TEST": {
|
||||
"value": "test"
|
||||
}
|
||||
}
|
||||
}
|
||||
"#;
|
||||
let config: CargoConfigFile = serde_json::from_str(raw).unwrap();
|
||||
let cwd = paths::Utf8PathBuf::try_from(std::env::current_dir().unwrap()).unwrap();
|
||||
let manifest = paths::AbsPathBuf::assert(cwd.join("Cargo.toml"));
|
||||
let manifest = ManifestPath::try_from(manifest).unwrap();
|
||||
let env = parse_output_cargo_config_env(&manifest, stdout);
|
||||
let env = cargo_config_env(&manifest, &Some(config));
|
||||
assert_eq!(env.get("CARGO_WORKSPACE_DIR").as_deref(), Some(cwd.join("").as_str()));
|
||||
assert_eq!(env.get("RELATIVE").as_deref(), Some(cwd.join("../relative").as_str()));
|
||||
assert_eq!(env.get("INVALID").as_deref(), Some("../relative"));
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ pub mod toolchain_info {
|
|||
|
||||
use std::path::Path;
|
||||
|
||||
use crate::{ManifestPath, Sysroot};
|
||||
use crate::{ManifestPath, Sysroot, cargo_config_file::CargoConfigFile};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum QueryConfig<'a> {
|
||||
|
|
@ -32,11 +32,12 @@ pub mod toolchain_info {
|
|||
Rustc(&'a Sysroot, &'a Path),
|
||||
/// Attempt to use cargo to query the desired information, honoring cargo configurations.
|
||||
/// If this fails, falls back to invoking `rustc` directly.
|
||||
Cargo(&'a Sysroot, &'a ManifestPath),
|
||||
Cargo(&'a Sysroot, &'a ManifestPath, &'a Option<CargoConfigFile>),
|
||||
}
|
||||
}
|
||||
|
||||
mod build_dependencies;
|
||||
mod cargo_config_file;
|
||||
mod cargo_workspace;
|
||||
mod env;
|
||||
mod manifest_path;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ fn rustc_print_cfg(
|
|||
) -> anyhow::Result<String> {
|
||||
const RUSTC_ARGS: [&str; 2] = ["--print", "cfg"];
|
||||
let (sysroot, current_dir) = match config {
|
||||
QueryConfig::Cargo(sysroot, cargo_toml) => {
|
||||
QueryConfig::Cargo(sysroot, cargo_toml, _) => {
|
||||
let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent(), extra_env);
|
||||
cmd.args(["rustc", "-Z", "unstable-options"]).args(RUSTC_ARGS);
|
||||
if let Some(target) = target {
|
||||
|
|
@ -109,7 +109,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_ne!(get(cfg, None, &FxHashMap::default()), vec![]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ pub fn get(
|
|||
})
|
||||
};
|
||||
let (sysroot, current_dir) = match config {
|
||||
QueryConfig::Cargo(sysroot, cargo_toml) => {
|
||||
QueryConfig::Cargo(sysroot, cargo_toml, _) => {
|
||||
let mut cmd = sysroot.tool(Tool::Cargo, cargo_toml.parent(), extra_env);
|
||||
cmd.env("RUSTC_BOOTSTRAP", "1");
|
||||
cmd.args(["rustc", "-Z", "unstable-options"]).args(RUSTC_ARGS).args([
|
||||
|
|
@ -66,7 +66,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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub(crate) fn get(
|
|||
extra_env: &FxHashMap<String, Option<String>>,
|
||||
) -> Result<Option<Version>, anyhow::Error> {
|
||||
let (mut cmd, prefix) = match config {
|
||||
QueryConfig::Cargo(sysroot, cargo_toml) => {
|
||||
QueryConfig::Cargo(sysroot, cargo_toml, _) => {
|
||||
(sysroot.tool(Tool::Cargo, cargo_toml.parent(), extra_env), "cargo ")
|
||||
}
|
||||
QueryConfig::Rustc(sysroot, current_dir) => {
|
||||
|
|
@ -44,7 +44,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, &FxHashMap::default()).is_ok());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,11 +25,9 @@ use crate::{
|
|||
ProjectJson, ProjectManifest, RustSourceWorkspaceConfig, Sysroot, TargetData, TargetKind,
|
||||
WorkspaceBuildScripts,
|
||||
build_dependencies::BuildScriptOutput,
|
||||
cargo_config_file,
|
||||
cargo_workspace::{CargoMetadataConfig, DepKind, PackageData, RustLibSource},
|
||||
env::{
|
||||
cargo_config_build_target_dir, cargo_config_env, inject_cargo_env,
|
||||
inject_cargo_package_env, inject_rustc_tool_env,
|
||||
},
|
||||
env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env},
|
||||
project_json::{Crate, CrateArrayIdx},
|
||||
sysroot::RustLibSrcWorkspace,
|
||||
toolchain_info::{QueryConfig, rustc_cfg, target_data_layout, target_tuple, version},
|
||||
|
|
@ -270,7 +268,9 @@ impl ProjectWorkspace {
|
|||
|
||||
tracing::info!(workspace = %cargo_toml, src_root = ?sysroot.rust_lib_src_root(), root = ?sysroot.root(), "Using sysroot");
|
||||
progress("querying project metadata".to_owned());
|
||||
let toolchain_config = QueryConfig::Cargo(&sysroot, cargo_toml);
|
||||
let config_file = cargo_config_file::read(cargo_toml, extra_env, &sysroot);
|
||||
let config_file_ = config_file.clone();
|
||||
let toolchain_config = QueryConfig::Cargo(&sysroot, cargo_toml, &config_file_);
|
||||
let targets =
|
||||
target_tuple::get(toolchain_config, target.as_deref(), extra_env).unwrap_or_default();
|
||||
let toolchain = version::get(toolchain_config, extra_env)
|
||||
|
|
@ -285,7 +285,7 @@ impl ProjectWorkspace {
|
|||
let target_dir = config
|
||||
.target_dir
|
||||
.clone()
|
||||
.or_else(|| cargo_config_build_target_dir(cargo_toml, extra_env, &sysroot))
|
||||
.or_else(|| cargo_target_dir(cargo_toml, extra_env, &sysroot))
|
||||
.unwrap_or_else(|| workspace_dir.join("target").into());
|
||||
|
||||
// We spawn a bunch of processes to query various information about the workspace's
|
||||
|
|
@ -397,7 +397,7 @@ impl ProjectWorkspace {
|
|||
)
|
||||
});
|
||||
let cargo_config_extra_env =
|
||||
s.spawn(|| cargo_config_env(cargo_toml, extra_env, &sysroot));
|
||||
s.spawn(move || cargo_config_env(cargo_toml, &config_file));
|
||||
thread::Result::Ok((
|
||||
rustc_cfg.join()?,
|
||||
data_layout.join()?,
|
||||
|
|
@ -476,9 +476,7 @@ impl ProjectWorkspace {
|
|||
let target_dir = config
|
||||
.target_dir
|
||||
.clone()
|
||||
.or_else(|| {
|
||||
cargo_config_build_target_dir(project_json.manifest()?, &config.extra_env, &sysroot)
|
||||
})
|
||||
.or_else(|| cargo_target_dir(project_json.manifest()?, &config.extra_env, &sysroot))
|
||||
.unwrap_or_else(|| project_root.join("target").into());
|
||||
|
||||
// We spawn a bunch of processes to query various information about the workspace's
|
||||
|
|
@ -554,7 +552,8 @@ impl ProjectWorkspace {
|
|||
None => Sysroot::empty(),
|
||||
};
|
||||
|
||||
let query_config = QueryConfig::Cargo(&sysroot, detached_file);
|
||||
let config_file = cargo_config_file::read(detached_file, &config.extra_env, &sysroot);
|
||||
let query_config = QueryConfig::Cargo(&sysroot, detached_file, &config_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();
|
||||
|
|
@ -563,7 +562,7 @@ impl ProjectWorkspace {
|
|||
let target_dir = config
|
||||
.target_dir
|
||||
.clone()
|
||||
.or_else(|| cargo_config_build_target_dir(detached_file, &config.extra_env, &sysroot))
|
||||
.or_else(|| cargo_target_dir(detached_file, &config.extra_env, &sysroot))
|
||||
.unwrap_or_else(|| dir.join("target").into());
|
||||
|
||||
let loaded_sysroot = sysroot.load_workspace(
|
||||
|
|
@ -600,8 +599,7 @@ impl ProjectWorkspace {
|
|||
)
|
||||
.ok()
|
||||
.map(|(ws, error)| {
|
||||
let cargo_config_extra_env =
|
||||
cargo_config_env(detached_file, &config.extra_env, &sysroot);
|
||||
let cargo_config_extra_env = cargo_config_env(detached_file, &config_file);
|
||||
(
|
||||
CargoWorkspace::new(ws, detached_file.clone(), cargo_config_extra_env, false),
|
||||
WorkspaceBuildScripts::default(),
|
||||
|
|
@ -1901,3 +1899,23 @@ fn sysroot_metadata_config(
|
|||
kind: "sysroot",
|
||||
}
|
||||
}
|
||||
|
||||
fn cargo_target_dir(
|
||||
manifest: &ManifestPath,
|
||||
extra_env: &FxHashMap<String, Option<String>>,
|
||||
sysroot: &Sysroot,
|
||||
) -> Option<Utf8PathBuf> {
|
||||
let cargo = sysroot.tool(Tool::Cargo, manifest.parent(), extra_env);
|
||||
let mut meta = cargo_metadata::MetadataCommand::new();
|
||||
meta.cargo_path(cargo.get_program());
|
||||
meta.manifest_path(manifest);
|
||||
// `--no-deps` doesn't (over)write lockfiles as it doesn't do any package resolve.
|
||||
// So we can use it to get `target_directory` before copying lockfiles
|
||||
let mut other_options = vec!["--no-deps".to_owned()];
|
||||
if manifest.is_rust_manifest() {
|
||||
meta.env("RUSTC_BOOTSTRAP", "1");
|
||||
other_options.push("-Zscript".to_owned());
|
||||
}
|
||||
meta.other_options(other_options);
|
||||
meta.exec().map(|m| m.target_directory).ok()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue