From 4fb79f2ca033a6ba8dc4797b62fe0015b117f280 Mon Sep 17 00:00:00 2001
From: Emil Lauridsen <mine809@gmail.com>
Date: Mon, 16 Mar 2020 14:17:32 +0100
Subject: [PATCH] Support specifying OUT_DIR in json project

---
 crates/ra_project_model/src/json_project.rs |  1 +
 crates/ra_project_model/src/lib.rs          | 24 ++++++++++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/crates/ra_project_model/src/json_project.rs b/crates/ra_project_model/src/json_project.rs
index 1bacb1d09a1..336446e58c3 100644
--- a/crates/ra_project_model/src/json_project.rs
+++ b/crates/ra_project_model/src/json_project.rs
@@ -22,6 +22,7 @@ pub struct Crate {
     pub(crate) deps: Vec<Dep>,
     pub(crate) atom_cfgs: FxHashSet<String>,
     pub(crate) key_value_cfgs: FxHashMap<String, String>,
+    pub(crate) out_dir: Option<PathBuf>,
 }
 
 #[derive(Clone, Copy, Debug, Deserialize)]
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs
index b2c3e576d5f..081b1fec2f5 100644
--- a/crates/ra_project_model/src/lib.rs
+++ b/crates/ra_project_model/src/lib.rs
@@ -152,7 +152,15 @@ impl ProjectWorkspace {
 
     pub fn out_dirs(&self) -> Vec<PathBuf> {
         match self {
-            ProjectWorkspace::Json { project: _project } => vec![],
+            ProjectWorkspace::Json { project } => {
+                let mut out_dirs = Vec::with_capacity(project.crates.len());
+                for krate in &project.crates {
+                    if let Some(out_dir) = &krate.out_dir {
+                        out_dirs.push(out_dir.to_path_buf());
+                    }
+                }
+                out_dirs
+            }
             ProjectWorkspace::Cargo { cargo, sysroot: _sysroot } => {
                 let mut out_dirs = Vec::with_capacity(cargo.packages().len());
                 for pkg in cargo.packages() {
@@ -202,6 +210,16 @@ impl ProjectWorkspace {
                             opts
                         };
 
+                        let mut env = Env::default();
+                        let mut extern_source = ExternSource::default();
+                        if let Some(out_dir) = &krate.out_dir {
+                            // FIXME: We probably mangle non UTF-8 paths here, figure out a better solution
+                            env.set("OUT_DIR", out_dir.to_string_lossy().to_string());
+                            if let Some(&extern_source_id) = extern_source_roots.get(out_dir) {
+                                extern_source.set_extern_path(&out_dir, extern_source_id);
+                            }
+                        }
+
                         // FIXME: No crate name in json definition such that we cannot add OUT_DIR to env
                         crates.insert(
                             crate_id,
@@ -211,8 +229,8 @@ impl ProjectWorkspace {
                                 // FIXME json definitions can store the crate name
                                 None,
                                 cfg_options,
-                                Env::default(),
-                                Default::default(),
+                                env,
+                                extern_source,
                             ),
                         );
                     }