Skip to content

Commit

Permalink
Read project environment vars from config
Browse files Browse the repository at this point in the history
Some custom build scripts (especially for -sys packages) expect to
query environment variables to locate build resources (such as
pre-built binaries) but these cause lots of trouble when considering
the numerous different ways in which cargo may be invoked.

For example each editor that invokes cargo as part of providing
development diagnostics needs to offer some way to configure environment
variables or users need to find their own way of controlling the environment
variables of these different tools which is burdensome and can lead
to an inconsistent duplication of state across tools.

This introduces support for reading an (optional) environment.json found
at the root of the current workspace that may contain a map of
environment variable key, value pairs. These variables will be exported
to all build scripts run under the workspace. The removes any need to
configure tools and editors independently.

The configuration is separate from any Config.toml since it's likely
that the state shouldn't be under version control in many situations
(generally locating resources for the project within a specific user's
development environment).

Fixes: rust-lang/issues/4121
Fixes: rust-lang/rls/issues/915
Fixes: rust-lang/vscode-rust/issues/791
Fixes: rust-lang/rust-analyzer/pull/6099
Fixes: intellij-rust/intellij-rust/issues/1569
  • Loading branch information
rib committed Nov 7, 2020
1 parent d5556ae commit cd248a5
Showing 1 changed file with 19 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ use crate::util::{self, internal, paths, profile};
use cargo_platform::Cfg;
use std::collections::hash_map::{Entry, HashMap};
use std::collections::{BTreeSet, HashSet};
use std::fs;
use std::path::{Path, PathBuf};
use std::str;
use std::sync::{Arc, Mutex};
use serde_json::Value;

const CARGO_WARNING: &str = "cargo:warning=";

Expand Down Expand Up @@ -208,6 +210,23 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
cmd.env("CARGO_MANIFEST_LINKS", links);
}

// Re-export environment variables declared in the project's environment.json
let env_path = Path::new(bcx.ws.root()).join("environment.json");
// TODO: cache the environment.json state with the Workspace so it doesn't
// need to be repeatedly read + parsed for each build script
if let Ok(env) = fs::read_to_string(env_path) {
let env: Value = serde_json::from_str(&env).expect("Failed to parse environment.json");
if let Some(env_map) = env.as_object() {
for key in env_map.keys() {
if let Some(env_value) = env[key].as_str() {
// Simply re-export as an actual environment variables so build scripts
// may continue to take their configuration from environment variables
cmd.env(key, env_value);
}
}
}
}

// Be sure to pass along all enabled features for this package, this is the
// last piece of statically known information that we have.
for feat in &unit.features {
Expand Down

0 comments on commit cd248a5

Please sign in to comment.