dinghy_build/
build_env.rs1use anyhow::{Context, Result};
17use std::env;
18use std::ffi::OsStr;
19use std::ffi::OsString;
20use std::path::PathBuf;
21
22pub fn append_path_to_env<K: AsRef<OsStr>, V: AsRef<OsStr>>(key: K, value: V) {
24 let mut formatted_value = OsString::new();
25 if let Ok(initial_value) = env::var(key.as_ref()) {
26 formatted_value.push(initial_value);
27 formatted_value.push(":");
28 }
29 formatted_value.push(value);
30 env::set_var(key.as_ref(), formatted_value);
31}
32
33pub fn append_path_to_target_env<K: AsRef<OsStr>, R: AsRef<str>, V: AsRef<OsStr>>(
36 k: K,
37 rustc_triple: Option<R>,
38 v: V,
39) {
40 append_path_to_env(target_key_from_triple(k, rustc_triple), v.as_ref())
41}
42
43pub fn build_env(name: &str) -> Result<String> {
48 let is_build_rs = env::var("CARGO_PKG_NAME").is_ok() && env::var("OUT_DIR").is_ok();
49
50 if is_build_rs {
51 println!("cargo:rerun-if-env-changed={}", name);
52 }
53 Ok(env::var(name)?)
54}
55
56pub fn envify<S: AsRef<str>>(name: S) -> String {
58 name.as_ref()
59 .chars()
60 .map(|c| c.to_ascii_uppercase())
61 .map(|c| if c == '-' || c == '.' { '_' } else { c })
62 .collect()
63}
64
65pub fn set_all_env<K: AsRef<OsStr>, V: AsRef<OsStr>>(env: &[(K, V)]) {
67 for env_var in env {
68 set_env(env_var.0.as_ref(), env_var.1.as_ref())
69 }
70}
71
72pub fn set_env<K: AsRef<OsStr>, V: AsRef<OsStr>>(k: K, v: V) {
74 log::debug!(
75 "Setting environment variable {:?}={:?}",
76 k.as_ref(),
77 v.as_ref()
78 );
79 env::set_var(k, v);
80}
81
82pub fn set_env_ifndef<K: AsRef<OsStr>, V: AsRef<OsStr>>(k: K, v: V) {
84 if let Ok(current_env_value) = env::var(k.as_ref()) {
85 log::debug!(
86 "Ignoring value {:?} as environment variable {:?} already defined with value {:?}",
87 k.as_ref(),
88 v.as_ref(),
89 current_env_value
90 );
91 } else {
92 log::debug!(
93 "Setting environment variable {:?}={:?}",
94 k.as_ref(),
95 v.as_ref()
96 );
97 env::set_var(k, v);
98 }
99}
100
101pub fn set_target_env<K: AsRef<OsStr>, R: AsRef<str>, V: AsRef<OsStr>>(
103 k: K,
104 rustc_triple: Option<R>,
105 v: V,
106) {
107 set_env(target_key_from_triple(k, rustc_triple), v);
108}
109
110pub fn sysroot_path() -> Result<PathBuf> {
113 env::var_os("TARGET_SYSROOT")
114 .map(PathBuf::from)
115 .context("You must either define a TARGET_SYSROOT or use Dinghy to build your project.")
116}
117
118pub fn target_env(var_base: &str) -> Result<String> {
121 if let Ok(target) = env::var("TARGET") {
122 let is_host = env::var("HOST")? == target;
123 target_env_from_triple(var_base, target.as_str(), is_host)
124 } else {
125 build_env(var_base)
126 }
127}
128
129pub fn target_env_from_triple(var_base: &str, triple: &str, is_host: bool) -> Result<String> {
131 build_env(&format!("{}_{}", var_base, triple))
132 .or_else(|_| build_env(&format!("{}_{}", var_base, triple.replace("-", "_"))))
133 .or_else(|_| {
134 build_env(&format!(
135 "{}_{}",
136 if is_host { "HOST" } else { "TARGET" },
137 var_base
138 ))
139 })
140 .or_else(|_| build_env(var_base))
141}
142
143fn target_key_from_triple<K: AsRef<OsStr>, R: AsRef<str>>(
144 k: K,
145 rustc_triple: Option<R>,
146) -> OsString {
147 let mut target_key = OsString::new();
148 target_key.push(k);
149 if let Some(rustc_triple) = rustc_triple {
150 target_key.push("_");
151 target_key.push(rustc_triple.as_ref().replace("-", "_"));
152 }
153 target_key
154}