about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2020-05-03 20:47:51 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2020-05-31 12:00:46 +0300
commit69b2179afe695d1a93b792cfd7c4197ca63ce658 (patch)
tree48a4458f5434f87fc6f288116d360e3808b6b62d
parentb6fa392238a459c29a47e2cf824d79a49a8ba039 (diff)
downloadrust-69b2179afe695d1a93b792cfd7c4197ca63ce658.tar.gz
rust-69b2179afe695d1a93b792cfd7c4197ca63ce658.zip
Print accessed env vars as special comments into depinfo files
-rw-r--r--src/librustc_builtin_macros/env.rs18
-rw-r--r--src/librustc_builtin_macros/lib.rs1
-rw-r--r--src/librustc_interface/passes.rs35
-rw-r--r--src/librustc_session/parse.rs3
-rw-r--r--src/test/run-make/env-dep-info/Makefile8
-rw-r--r--src/test/run-make/env-dep-info/main.rs6
6 files changed, 64 insertions, 7 deletions
diff --git a/src/librustc_builtin_macros/env.rs b/src/librustc_builtin_macros/env.rs
index d769ebb1f55..6c3a1ce0958 100644
--- a/src/librustc_builtin_macros/env.rs
+++ b/src/librustc_builtin_macros/env.rs
@@ -22,8 +22,10 @@ pub fn expand_option_env<'cx>(
     };
 
     let sp = cx.with_def_site_ctxt(sp);
-    let e = match env::var(&var.as_str()) {
-        Err(..) => {
+    let value = env::var(&var.as_str()).ok().as_deref().map(Symbol::intern);
+    cx.parse_sess.env_depinfo.borrow_mut().insert((Symbol::intern(&var), value));
+    let e = match value {
+        None => {
             let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp));
             cx.expr_path(cx.path_all(
                 sp,
@@ -37,10 +39,10 @@ pub fn expand_option_env<'cx>(
                 ))],
             ))
         }
-        Ok(s) => cx.expr_call_global(
+        Some(value) => cx.expr_call_global(
             sp,
             cx.std_path(&[sym::option, sym::Option, sym::Some]),
-            vec![cx.expr_str(sp, Symbol::intern(&s))],
+            vec![cx.expr_str(sp, value)],
         ),
     };
     MacEager::expr(e)
@@ -78,12 +80,14 @@ pub fn expand_env<'cx>(
     }
 
     let sp = cx.with_def_site_ctxt(sp);
-    let e = match env::var(&*var.as_str()) {
-        Err(_) => {
+    let value = env::var(&*var.as_str()).ok().as_deref().map(Symbol::intern);
+    cx.parse_sess.env_depinfo.borrow_mut().insert((var, value));
+    let e = match value {
+        None => {
             cx.span_err(sp, &msg.as_str());
             return DummyResult::any(sp);
         }
-        Ok(s) => cx.expr_str(sp, Symbol::intern(&s)),
+        Some(value) => cx.expr_str(sp, value),
     };
     MacEager::expr(e)
 }
diff --git a/src/librustc_builtin_macros/lib.rs b/src/librustc_builtin_macros/lib.rs
index a0f82d65618..f56d8a372a7 100644
--- a/src/librustc_builtin_macros/lib.rs
+++ b/src/librustc_builtin_macros/lib.rs
@@ -5,6 +5,7 @@
 #![feature(bool_to_option)]
 #![feature(crate_visibility_modifier)]
 #![feature(decl_macro)]
+#![feature(inner_deref)]
 #![feature(nll)]
 #![feature(or_patterns)]
 #![feature(proc_macro_internals)]
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index c06fd91133b..5af0ba2afb9 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -540,6 +540,22 @@ fn escape_dep_filename(filename: &FileName) -> String {
     filename.to_string().replace(" ", "\\ ")
 }
 
+// Makefile comments only need escaping newlines and `\`.
+// The result can be unescaped by anything that can unescape `escape_default` and friends.
+fn escape_dep_env(symbol: Symbol) -> String {
+    let s = symbol.as_str();
+    let mut escaped = String::with_capacity(s.len());
+    for c in s.chars() {
+        match c {
+            '\n' => escaped.push_str(r"\n"),
+            '\r' => escaped.push_str(r"\r"),
+            '\\' => escaped.push_str(r"\\"),
+            _ => escaped.push(c),
+        }
+    }
+    escaped
+}
+
 fn write_out_deps(
     sess: &Session,
     boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
@@ -592,6 +608,25 @@ fn write_out_deps(
         for path in files {
             writeln!(file, "{}:", path)?;
         }
+
+        // Emit special comments with information about accessed environment variables.
+        let env_depinfo = sess.parse_sess.env_depinfo.borrow();
+        if !env_depinfo.is_empty() {
+            let mut envs: Vec<_> = env_depinfo
+                .iter()
+                .map(|(k, v)| (escape_dep_env(*k), v.map(escape_dep_env)))
+                .collect();
+            envs.sort_unstable();
+            writeln!(file)?;
+            for (k, v) in envs {
+                write!(file, "# env-dep:{}", k)?;
+                if let Some(v) = v {
+                    write!(file, "={}", v)?;
+                }
+                writeln!(file)?;
+            }
+        }
+
         Ok(())
     })();
 
diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs
index 233761dbed7..aaae5889117 100644
--- a/src/librustc_session/parse.rs
+++ b/src/librustc_session/parse.rs
@@ -135,6 +135,8 @@ pub struct ParseSess {
     pub symbol_gallery: SymbolGallery,
     /// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors.
     pub reached_eof: Lock<bool>,
+    /// Environment variables accessed during the build and their values when they exist.
+    pub env_depinfo: Lock<FxHashSet<(Symbol, Option<Symbol>)>>,
 }
 
 impl ParseSess {
@@ -160,6 +162,7 @@ impl ParseSess {
             gated_spans: GatedSpans::default(),
             symbol_gallery: SymbolGallery::default(),
             reached_eof: Lock::new(false),
+            env_depinfo: Default::default(),
         }
     }
 
diff --git a/src/test/run-make/env-dep-info/Makefile b/src/test/run-make/env-dep-info/Makefile
new file mode 100644
index 00000000000..2be0b4b324b
--- /dev/null
+++ b/src/test/run-make/env-dep-info/Makefile
@@ -0,0 +1,8 @@
+-include ../../run-make-fulldeps/tools.mk
+
+all:
+	EXISTING_ENV=1 EXISTING_OPT_ENV=1 $(RUSTC) --emit dep-info main.rs
+	$(CGREP) "# env-dep:EXISTING_ENV=1" < $(TMPDIR)/main.d
+	$(CGREP) "# env-dep:EXISTING_OPT_ENV=1" < $(TMPDIR)/main.d
+	$(CGREP) "# env-dep:NONEXISTENT_OPT_ENV" < $(TMPDIR)/main.d
+	$(CGREP) "# env-dep:ESCAPE\nESCAPE\\" < $(TMPDIR)/main.d
diff --git a/src/test/run-make/env-dep-info/main.rs b/src/test/run-make/env-dep-info/main.rs
new file mode 100644
index 00000000000..a25246bac79
--- /dev/null
+++ b/src/test/run-make/env-dep-info/main.rs
@@ -0,0 +1,6 @@
+fn main() {
+    env!("EXISTING_ENV");
+    option_env!("EXISTING_OPT_ENV");
+    option_env!("NONEXISTENT_OPT_ENV");
+    option_env!("ESCAPE\nESCAPE\\");
+}