mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +00:00
Cleanup cfg and env handling in project-model
This commit is contained in:
parent
2e54c0af40
commit
ee10f9f5cd
9 changed files with 193 additions and 114 deletions
|
@ -331,10 +331,11 @@ impl CrateGraph {
|
|||
version: Option<String>,
|
||||
cfg_options: Arc<CfgOptions>,
|
||||
potential_cfg_options: Option<Arc<CfgOptions>>,
|
||||
env: Env,
|
||||
mut env: Env,
|
||||
is_proc_macro: bool,
|
||||
origin: CrateOrigin,
|
||||
) -> CrateId {
|
||||
env.entries.shrink_to_fit();
|
||||
let data = CrateData {
|
||||
root_file_id,
|
||||
edition,
|
||||
|
@ -651,8 +652,8 @@ impl FromIterator<(String, String)> for Env {
|
|||
}
|
||||
|
||||
impl Env {
|
||||
pub fn set(&mut self, env: &str, value: String) {
|
||||
self.entries.insert(env.to_owned(), value);
|
||||
pub fn set(&mut self, env: &str, value: impl Into<String>) {
|
||||
self.entries.insert(env.to_owned(), value.into());
|
||||
}
|
||||
|
||||
pub fn get(&self, env: &str) -> Option<String> {
|
||||
|
|
|
@ -23,16 +23,18 @@ use serde::Deserialize;
|
|||
use toolchain::Tool;
|
||||
|
||||
use crate::{
|
||||
cfg_flag::CfgFlag, utf8_stdout, CargoConfig, CargoFeatures, CargoWorkspace, InvocationLocation,
|
||||
cfg::CfgFlag, utf8_stdout, CargoConfig, CargoFeatures, CargoWorkspace, InvocationLocation,
|
||||
InvocationStrategy, Package, Sysroot, TargetKind,
|
||||
};
|
||||
|
||||
/// Output of the build script and proc-macro building steps for a workspace.
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub struct WorkspaceBuildScripts {
|
||||
outputs: ArenaMap<Package, BuildScriptOutput>,
|
||||
error: Option<String>,
|
||||
}
|
||||
|
||||
/// Output of the build script and proc-macro building step for a concrete package.
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
||||
pub(crate) struct BuildScriptOutput {
|
||||
/// List of config flags defined by this package's build script.
|
||||
|
|
|
@ -135,6 +135,20 @@ pub struct PackageData {
|
|||
pub active_features: Vec<String>,
|
||||
/// String representation of package id
|
||||
pub id: String,
|
||||
/// Authors as given in the `Cargo.toml`
|
||||
pub authors: Vec<String>,
|
||||
/// Description as given in the `Cargo.toml`
|
||||
pub description: Option<String>,
|
||||
/// Homepage as given in the `Cargo.toml`
|
||||
pub homepage: Option<String>,
|
||||
/// License as given in the `Cargo.toml`
|
||||
pub license: Option<String>,
|
||||
/// License file as given in the `Cargo.toml`
|
||||
pub license_file: Option<Utf8PathBuf>,
|
||||
/// Readme file as given in the `Cargo.toml`
|
||||
pub readme: Option<Utf8PathBuf>,
|
||||
/// Rust version as given in the `Cargo.toml`
|
||||
pub rust_version: Option<semver::Version>,
|
||||
/// The contents of [package.metadata.rust-analyzer]
|
||||
pub metadata: RustAnalyzerPackageMetaData,
|
||||
}
|
||||
|
@ -225,6 +239,10 @@ impl TargetKind {
|
|||
}
|
||||
TargetKind::Other
|
||||
}
|
||||
|
||||
pub fn is_executable(self) -> bool {
|
||||
matches!(self, TargetKind::Bin | TargetKind::Example)
|
||||
}
|
||||
}
|
||||
|
||||
// Deserialize helper for the cargo metadata
|
||||
|
@ -330,6 +348,13 @@ impl CargoWorkspace {
|
|||
repository,
|
||||
edition,
|
||||
metadata,
|
||||
authors,
|
||||
description,
|
||||
homepage,
|
||||
license,
|
||||
license_file,
|
||||
readme,
|
||||
rust_version,
|
||||
..
|
||||
} = meta_pkg;
|
||||
let meta = from_value::<PackageMetadata>(metadata).unwrap_or_default();
|
||||
|
@ -358,6 +383,13 @@ impl CargoWorkspace {
|
|||
is_member,
|
||||
edition,
|
||||
repository,
|
||||
authors,
|
||||
description,
|
||||
homepage,
|
||||
license,
|
||||
license_file,
|
||||
readme,
|
||||
rust_version,
|
||||
dependencies: Vec::new(),
|
||||
features: features.into_iter().collect(),
|
||||
active_features: Vec::new(),
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
//! rustc main.rs --cfg foo --cfg 'feature="bar"'
|
||||
use std::{fmt, str::FromStr};
|
||||
|
||||
use cfg::CfgOptions;
|
||||
use cfg::{CfgDiff, CfgOptions};
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Debug, Serialize)]
|
||||
|
@ -70,3 +71,27 @@ impl fmt::Display for CfgFlag {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A set of cfg-overrides per crate.
|
||||
#[derive(Default, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct CfgOverrides {
|
||||
/// A global set of overrides matching all crates.
|
||||
pub global: CfgDiff,
|
||||
/// A set of overrides matching specific crates.
|
||||
pub selective: FxHashMap<String, CfgDiff>,
|
||||
}
|
||||
|
||||
impl CfgOverrides {
|
||||
pub fn len(&self) -> usize {
|
||||
self.global.len() + self.selective.values().map(|it| it.len()).sum::<usize>()
|
||||
}
|
||||
|
||||
pub fn apply(&self, cfg_options: &mut CfgOptions, name: &str) {
|
||||
if !self.global.is_empty() {
|
||||
cfg_options.apply_diff(self.global.clone());
|
||||
};
|
||||
if let Some(diff) = self.selective.get(name) {
|
||||
cfg_options.apply_diff(diff.clone());
|
||||
};
|
||||
}
|
||||
}
|
84
crates/project-model/src/env.rs
Normal file
84
crates/project-model/src/env.rs
Normal file
|
@ -0,0 +1,84 @@
|
|||
use base_db::Env;
|
||||
use rustc_hash::FxHashMap;
|
||||
use toolchain::Tool;
|
||||
|
||||
use crate::{utf8_stdout, ManifestPath, PackageData, Sysroot, TargetKind};
|
||||
|
||||
/// Recreates the compile-time environment variables that Cargo sets.
|
||||
///
|
||||
/// Should be synced with
|
||||
/// <https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates>
|
||||
///
|
||||
/// FIXME: ask Cargo to provide this data instead of re-deriving.
|
||||
pub(crate) fn inject_cargo_package_env(env: &mut Env, package: &PackageData) {
|
||||
// FIXME: Missing variables:
|
||||
// CARGO_BIN_NAME, CARGO_BIN_EXE_<name>
|
||||
|
||||
let manifest_dir = package.manifest.parent();
|
||||
env.set("CARGO_MANIFEST_DIR", manifest_dir.as_str());
|
||||
|
||||
env.set("CARGO_PKG_VERSION", package.version.to_string());
|
||||
env.set("CARGO_PKG_VERSION_MAJOR", package.version.major.to_string());
|
||||
env.set("CARGO_PKG_VERSION_MINOR", package.version.minor.to_string());
|
||||
env.set("CARGO_PKG_VERSION_PATCH", package.version.patch.to_string());
|
||||
env.set("CARGO_PKG_VERSION_PRE", package.version.pre.to_string());
|
||||
|
||||
env.set("CARGO_PKG_AUTHORS", package.authors.join(":").clone());
|
||||
|
||||
env.set("CARGO_PKG_NAME", package.name.clone());
|
||||
env.set("CARGO_PKG_DESCRIPTION", package.description.as_deref().unwrap_or_default());
|
||||
env.set("CARGO_PKG_HOMEPAGE", package.homepage.as_deref().unwrap_or_default());
|
||||
env.set("CARGO_PKG_REPOSITORY", package.repository.as_deref().unwrap_or_default());
|
||||
env.set("CARGO_PKG_LICENSE", package.license.as_deref().unwrap_or_default());
|
||||
env.set(
|
||||
"CARGO_PKG_LICENSE_FILE",
|
||||
package.license_file.as_ref().map(ToString::to_string).unwrap_or_default(),
|
||||
);
|
||||
env.set(
|
||||
"CARGO_PKG_README",
|
||||
package.readme.as_ref().map(ToString::to_string).unwrap_or_default(),
|
||||
);
|
||||
|
||||
env.set(
|
||||
"CARGO_PKG_RUST_VERSION",
|
||||
package.rust_version.as_ref().map(ToString::to_string).unwrap_or_default(),
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn inject_cargo_env(env: &mut Env) {
|
||||
env.set("CARGO", Tool::Cargo.path().to_string());
|
||||
}
|
||||
|
||||
pub(crate) fn inject_rustc_tool_env(env: &mut Env, cargo_name: &str, kind: TargetKind) {
|
||||
_ = kind;
|
||||
// FIXME
|
||||
// if kind.is_executable() {
|
||||
// env.set("CARGO_BIN_NAME", cargo_name);
|
||||
// }
|
||||
env.set("CARGO_CRATE_NAME", cargo_name.replace('-', "_"));
|
||||
}
|
||||
|
||||
pub(crate) fn cargo_config_env(
|
||||
cargo_toml: &ManifestPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
sysroot: Option<&Sysroot>,
|
||||
) -> FxHashMap<String, String> {
|
||||
let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo);
|
||||
cargo_config.envs(extra_env);
|
||||
cargo_config
|
||||
.current_dir(cargo_toml.parent())
|
||||
.args(["-Z", "unstable-options", "config", "get", "env"])
|
||||
.env("RUSTC_BOOTSTRAP", "1");
|
||||
// if successful we receive `env.key.value = "value" per entry
|
||||
tracing::debug!("Discovering cargo config env by {:?}", cargo_config);
|
||||
utf8_stdout(cargo_config).map(parse_output_cargo_config_env).unwrap_or_default()
|
||||
}
|
||||
|
||||
fn parse_output_cargo_config_env(stdout: String) -> FxHashMap<String, String> {
|
||||
stdout
|
||||
.lines()
|
||||
.filter_map(|l| l.strip_prefix("env."))
|
||||
.filter_map(|l| l.split_once(".value = "))
|
||||
.map(|(key, value)| (key.to_owned(), value.trim_matches('"').to_owned()))
|
||||
.collect()
|
||||
}
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
mod build_scripts;
|
||||
mod cargo_workspace;
|
||||
mod cfg_flag;
|
||||
mod cfg;
|
||||
mod env;
|
||||
mod manifest_path;
|
||||
mod project_json;
|
||||
mod rustc_cfg;
|
||||
|
@ -47,10 +48,11 @@ pub use crate::{
|
|||
CargoConfig, CargoFeatures, CargoWorkspace, Package, PackageData, PackageDependency,
|
||||
RustLibSource, Target, TargetData, TargetKind,
|
||||
},
|
||||
cfg::CfgOverrides,
|
||||
manifest_path::ManifestPath,
|
||||
project_json::{ProjectJson, ProjectJsonData},
|
||||
sysroot::Sysroot,
|
||||
workspace::{CfgOverrides, PackageRoot, ProjectWorkspace},
|
||||
workspace::{FileLoader, PackageRoot, ProjectWorkspace},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
|
|
|
@ -55,7 +55,7 @@ use rustc_hash::FxHashMap;
|
|||
use serde::{de, Deserialize, Serialize};
|
||||
use span::Edition;
|
||||
|
||||
use crate::cfg_flag::CfgFlag;
|
||||
use crate::cfg::CfgFlag;
|
||||
|
||||
/// Roots and crates that compose this Rust project.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
|
|
|
@ -4,7 +4,7 @@ use anyhow::Context;
|
|||
use rustc_hash::FxHashMap;
|
||||
use toolchain::Tool;
|
||||
|
||||
use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath, Sysroot};
|
||||
use crate::{cfg::CfgFlag, utf8_stdout, ManifestPath, Sysroot};
|
||||
|
||||
/// Determines how `rustc --print cfg` is discovered and invoked.
|
||||
pub(crate) enum RustcCfgConfig<'a> {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//! metadata` or `rust-project.json`) into representation stored in the salsa
|
||||
//! database -- `CrateGraph`.
|
||||
|
||||
use std::{collections::VecDeque, fmt, fs, iter, str::FromStr, sync};
|
||||
use std::{collections::VecDeque, fmt, fs, iter, sync};
|
||||
|
||||
use anyhow::{format_err, Context};
|
||||
use base_db::{
|
||||
|
@ -21,7 +21,8 @@ use triomphe::Arc;
|
|||
use crate::{
|
||||
build_scripts::BuildScriptOutput,
|
||||
cargo_workspace::{DepKind, PackageData, RustLibSource},
|
||||
cfg_flag::CfgFlag,
|
||||
cfg::{CfgFlag, CfgOverrides},
|
||||
env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env},
|
||||
project_json::{Crate, CrateArrayIdx},
|
||||
rustc_cfg::{self, RustcCfgConfig},
|
||||
sysroot::{SysrootCrate, SysrootMode},
|
||||
|
@ -30,29 +31,7 @@ use crate::{
|
|||
ProjectJson, ProjectManifest, Sysroot, TargetData, TargetKind, WorkspaceBuildScripts,
|
||||
};
|
||||
|
||||
/// A set of cfg-overrides per crate.
|
||||
#[derive(Default, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct CfgOverrides {
|
||||
/// A global set of overrides matching all crates.
|
||||
pub global: CfgDiff,
|
||||
/// A set of overrides matching specific crates.
|
||||
pub selective: FxHashMap<String, CfgDiff>,
|
||||
}
|
||||
|
||||
impl CfgOverrides {
|
||||
pub fn len(&self) -> usize {
|
||||
self.global.len() + self.selective.values().map(|it| it.len()).sum::<usize>()
|
||||
}
|
||||
|
||||
fn apply(&self, cfg_options: &mut CfgOptions, name: &str) {
|
||||
if !self.global.is_empty() {
|
||||
cfg_options.apply_diff(self.global.clone());
|
||||
};
|
||||
if let Some(diff) = self.selective.get(name) {
|
||||
cfg_options.apply_diff(diff.clone());
|
||||
};
|
||||
}
|
||||
}
|
||||
pub type FileLoader<'a> = &'a mut dyn for<'b> FnMut(&'b AbsPath) -> Option<FileId>;
|
||||
|
||||
/// `PackageRoot` describes a package root folder.
|
||||
/// Which may be an external dependency, or a member of
|
||||
|
@ -69,29 +48,43 @@ pub struct PackageRoot {
|
|||
pub enum ProjectWorkspace {
|
||||
/// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
|
||||
Cargo {
|
||||
/// The workspace as returned by `cargo metadata`.
|
||||
cargo: CargoWorkspace,
|
||||
/// The build script results for the workspace.
|
||||
build_scripts: WorkspaceBuildScripts,
|
||||
/// The sysroot loaded for this workspace.
|
||||
sysroot: Result<Sysroot, Option<String>>,
|
||||
/// The rustc workspace loaded for this workspace. An `Err(None)` means loading has been
|
||||
/// disabled or was otherwise not requested.
|
||||
rustc: Result<Box<(CargoWorkspace, WorkspaceBuildScripts)>, Option<String>>,
|
||||
/// Holds cfg flags for the current target. We get those by running
|
||||
/// `rustc --print cfg`.
|
||||
///
|
||||
/// FIXME: make this a per-crate map, as, eg, build.rs might have a
|
||||
/// different target.
|
||||
// FIXME: make this a per-crate map, as, eg, build.rs might have a
|
||||
// different target.
|
||||
rustc_cfg: Vec<CfgFlag>,
|
||||
/// A set of cfg overrides for this workspace.
|
||||
cfg_overrides: CfgOverrides,
|
||||
/// The toolchain version used by this workspace.
|
||||
toolchain: Option<Version>,
|
||||
/// The target data layout queried for workspace.
|
||||
target_layout: TargetLayoutLoadResult,
|
||||
/// Environment variables set in the `.cargo/config` file.
|
||||
cargo_config_extra_env: FxHashMap<String, String>,
|
||||
},
|
||||
/// Project workspace was manually specified using a `rust-project.json` file.
|
||||
Json {
|
||||
/// The loaded project json file.
|
||||
project: ProjectJson,
|
||||
/// The sysroot loaded for this workspace.
|
||||
sysroot: Result<Sysroot, Option<String>>,
|
||||
/// Holds cfg flags for the current target. We get those by running
|
||||
/// `rustc --print cfg`.
|
||||
// FIXME: make this a per-crate map, as, eg, build.rs might have a
|
||||
// different target.
|
||||
rustc_cfg: Vec<CfgFlag>,
|
||||
/// The toolchain version used by this workspace.
|
||||
toolchain: Option<Version>,
|
||||
/// The target data layout queried for workspace.
|
||||
target_layout: TargetLayoutLoadResult,
|
||||
},
|
||||
// FIXME: The primary limitation of this approach is that the set of detached files needs to be fixed at the beginning.
|
||||
|
@ -105,12 +98,18 @@ pub enum ProjectWorkspace {
|
|||
/// Project with a set of disjoint files, not belonging to any particular workspace.
|
||||
/// Backed by basic sysroot crates for basic completion and highlighting.
|
||||
DetachedFiles {
|
||||
/// The set of detached files.
|
||||
files: Vec<AbsPathBuf>,
|
||||
/// The sysroot loaded for this workspace.
|
||||
sysroot: Result<Sysroot, Option<String>>,
|
||||
/// Holds cfg flags for the current target. We get those by running
|
||||
/// `rustc --print cfg`.
|
||||
// FIXME: make this a per-crate map, as, eg, build.rs might have a
|
||||
// different target.
|
||||
rustc_cfg: Vec<CfgFlag>,
|
||||
/// The toolchain version used by this workspace.
|
||||
toolchain: Option<Version>,
|
||||
/// The target data layout queried for workspace.
|
||||
target_layout: TargetLayoutLoadResult,
|
||||
},
|
||||
}
|
||||
|
@ -723,7 +722,7 @@ impl ProjectWorkspace {
|
|||
|
||||
pub fn to_crate_graph(
|
||||
&self,
|
||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||
load: FileLoader<'_>,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
) -> (CrateGraph, ProcMacroPaths) {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "ProjectWorkspace::to_crate_graph").entered();
|
||||
|
@ -874,7 +873,7 @@ impl ProjectWorkspace {
|
|||
|
||||
fn project_json_to_crate_graph(
|
||||
rustc_cfg: Vec<CfgFlag>,
|
||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||
load: FileLoader<'_>,
|
||||
project: &ProjectJson,
|
||||
sysroot: Option<&Sysroot>,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
|
@ -976,7 +975,7 @@ fn project_json_to_crate_graph(
|
|||
}
|
||||
|
||||
fn cargo_to_crate_graph(
|
||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||
load: FileLoader<'_>,
|
||||
rustc: Option<&(CargoWorkspace, WorkspaceBuildScripts)>,
|
||||
cargo: &CargoWorkspace,
|
||||
sysroot: Option<&Sysroot>,
|
||||
|
@ -1166,7 +1165,7 @@ fn cargo_to_crate_graph(
|
|||
|
||||
fn detached_files_to_crate_graph(
|
||||
rustc_cfg: Vec<CfgFlag>,
|
||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||
load: FileLoader<'_>,
|
||||
detached_files: &[AbsPathBuf],
|
||||
sysroot: Option<&Sysroot>,
|
||||
) -> (CrateGraph, ProcMacroPaths) {
|
||||
|
@ -1216,7 +1215,7 @@ fn handle_rustc_crates(
|
|||
crate_graph: &mut CrateGraph,
|
||||
proc_macros: &mut ProcMacroPaths,
|
||||
pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
|
||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||
load: FileLoader<'_>,
|
||||
rustc_workspace: &CargoWorkspace,
|
||||
cargo: &CargoWorkspace,
|
||||
public_deps: &SysrootPublicDeps,
|
||||
|
@ -1350,23 +1349,19 @@ fn add_target_crate_root(
|
|||
};
|
||||
|
||||
let mut env = Env::default();
|
||||
inject_cargo_env(pkg, &mut env);
|
||||
if let Ok(cname) = String::from_str(cargo_name) {
|
||||
// CARGO_CRATE_NAME is the name of the Cargo target with - converted to _, such as the name of the library, binary, example, integration test, or benchmark.
|
||||
env.set("CARGO_CRATE_NAME", cname.replace('-', "_"));
|
||||
}
|
||||
inject_cargo_package_env(&mut env, pkg);
|
||||
inject_cargo_env(&mut env);
|
||||
inject_rustc_tool_env(&mut env, cargo_name, kind);
|
||||
|
||||
if let Some(envs) = build_data.map(|it| &it.envs) {
|
||||
for (k, v) in envs {
|
||||
env.set(k, v.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let display_name = CrateDisplayName::from_canonical_name(cargo_name.to_owned());
|
||||
let crate_id = crate_graph.add_crate_root(
|
||||
file_id,
|
||||
edition,
|
||||
Some(display_name),
|
||||
Some(CrateDisplayName::from_canonical_name(cargo_name.to_owned())),
|
||||
Some(pkg.version.to_string()),
|
||||
Arc::new(cfg_options),
|
||||
potential_cfg_options.map(Arc::new),
|
||||
|
@ -1405,7 +1400,7 @@ fn sysroot_to_crate_graph(
|
|||
crate_graph: &mut CrateGraph,
|
||||
sysroot: &Sysroot,
|
||||
rustc_cfg: Vec<CfgFlag>,
|
||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||
load: FileLoader<'_>,
|
||||
) -> (SysrootPublicDeps, Option<CrateId>) {
|
||||
let _p = tracing::span!(tracing::Level::INFO, "sysroot_to_crate_graph").entered();
|
||||
match sysroot.mode() {
|
||||
|
@ -1480,7 +1475,6 @@ fn sysroot_to_crate_graph(
|
|||
.filter_map(|krate| {
|
||||
let file_id = load(&stitched[krate].root)?;
|
||||
|
||||
let env = Env::default();
|
||||
let display_name =
|
||||
CrateDisplayName::from_canonical_name(stitched[krate].name.clone());
|
||||
let crate_id = crate_graph.add_crate_root(
|
||||
|
@ -1490,7 +1484,7 @@ fn sysroot_to_crate_graph(
|
|||
None,
|
||||
cfg_options.clone(),
|
||||
None,
|
||||
env,
|
||||
Env::default(),
|
||||
false,
|
||||
CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)),
|
||||
);
|
||||
|
@ -1549,70 +1543,9 @@ fn add_dep_inner(graph: &mut CrateGraph, from: CrateId, dep: Dependency) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Recreates the compile-time environment variables that Cargo sets.
|
||||
///
|
||||
/// Should be synced with
|
||||
/// <https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates>
|
||||
///
|
||||
/// FIXME: ask Cargo to provide this data instead of re-deriving.
|
||||
fn inject_cargo_env(package: &PackageData, env: &mut Env) {
|
||||
// FIXME: Missing variables:
|
||||
// CARGO_BIN_NAME, CARGO_BIN_EXE_<name>
|
||||
|
||||
let manifest_dir = package.manifest.parent();
|
||||
env.set("CARGO_MANIFEST_DIR", manifest_dir.as_str().to_owned());
|
||||
|
||||
// Not always right, but works for common cases.
|
||||
env.set("CARGO", "cargo".into());
|
||||
|
||||
env.set("CARGO_PKG_VERSION", package.version.to_string());
|
||||
env.set("CARGO_PKG_VERSION_MAJOR", package.version.major.to_string());
|
||||
env.set("CARGO_PKG_VERSION_MINOR", package.version.minor.to_string());
|
||||
env.set("CARGO_PKG_VERSION_PATCH", package.version.patch.to_string());
|
||||
env.set("CARGO_PKG_VERSION_PRE", package.version.pre.to_string());
|
||||
|
||||
env.set("CARGO_PKG_AUTHORS", String::new());
|
||||
|
||||
env.set("CARGO_PKG_NAME", package.name.clone());
|
||||
// FIXME: This isn't really correct (a package can have many crates with different names), but
|
||||
// it's better than leaving the variable unset.
|
||||
env.set("CARGO_CRATE_NAME", CrateName::normalize_dashes(&package.name).to_string());
|
||||
env.set("CARGO_PKG_DESCRIPTION", String::new());
|
||||
env.set("CARGO_PKG_HOMEPAGE", String::new());
|
||||
env.set("CARGO_PKG_REPOSITORY", String::new());
|
||||
env.set("CARGO_PKG_LICENSE", String::new());
|
||||
|
||||
env.set("CARGO_PKG_LICENSE_FILE", String::new());
|
||||
}
|
||||
|
||||
fn create_cfg_options(rustc_cfg: Vec<CfgFlag>) -> CfgOptions {
|
||||
let mut cfg_options = CfgOptions::default();
|
||||
cfg_options.extend(rustc_cfg);
|
||||
cfg_options.insert_atom("debug_assertions".into());
|
||||
cfg_options
|
||||
}
|
||||
|
||||
fn cargo_config_env(
|
||||
cargo_toml: &ManifestPath,
|
||||
extra_env: &FxHashMap<String, String>,
|
||||
sysroot: Option<&Sysroot>,
|
||||
) -> FxHashMap<String, String> {
|
||||
let mut cargo_config = Sysroot::tool(sysroot, Tool::Cargo);
|
||||
cargo_config.envs(extra_env);
|
||||
cargo_config
|
||||
.current_dir(cargo_toml.parent())
|
||||
.args(["-Z", "unstable-options", "config", "get", "env"])
|
||||
.env("RUSTC_BOOTSTRAP", "1");
|
||||
// if successful we receive `env.key.value = "value" per entry
|
||||
tracing::debug!("Discovering cargo config env by {:?}", cargo_config);
|
||||
utf8_stdout(cargo_config).map(parse_output_cargo_config_env).unwrap_or_default()
|
||||
}
|
||||
|
||||
fn parse_output_cargo_config_env(stdout: String) -> FxHashMap<String, String> {
|
||||
stdout
|
||||
.lines()
|
||||
.filter_map(|l| l.strip_prefix("env."))
|
||||
.filter_map(|l| l.split_once(".value = "))
|
||||
.map(|(key, value)| (key.to_owned(), value.trim_matches('"').to_owned()))
|
||||
.collect()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue