aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_project_model/src/cargo_workspace.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_project_model/src/cargo_workspace.rs')
-rw-r--r--crates/ra_project_model/src/cargo_workspace.rs35
1 files changed, 20 insertions, 15 deletions
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs
index 362ee30fe..a306ce95f 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/ra_project_model/src/cargo_workspace.rs
@@ -1,7 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::{ 3use std::{
4 env,
5 ffi::OsStr, 4 ffi::OsStr,
6 ops, 5 ops,
7 path::{Path, PathBuf}, 6 path::{Path, PathBuf},
@@ -56,6 +55,9 @@ pub struct CargoConfig {
56 55
57 /// Runs cargo check on launch to figure out the correct values of OUT_DIR 56 /// Runs cargo check on launch to figure out the correct values of OUT_DIR
58 pub load_out_dirs_from_check: bool, 57 pub load_out_dirs_from_check: bool,
58
59 /// rustc target
60 pub target: Option<String>,
59} 61}
60 62
61impl Default for CargoConfig { 63impl Default for CargoConfig {
@@ -65,6 +67,7 @@ impl Default for CargoConfig {
65 all_features: true, 67 all_features: true,
66 features: Vec::new(), 68 features: Vec::new(),
67 load_out_dirs_from_check: false, 69 load_out_dirs_from_check: false,
70 target: None,
68 } 71 }
69 } 72 }
70} 73}
@@ -83,6 +86,7 @@ pub struct PackageData {
83 pub dependencies: Vec<PackageDependency>, 86 pub dependencies: Vec<PackageDependency>,
84 pub edition: Edition, 87 pub edition: Edition,
85 pub features: Vec<String>, 88 pub features: Vec<String>,
89 pub cfgs: Vec<String>,
86 pub out_dir: Option<PathBuf>, 90 pub out_dir: Option<PathBuf>,
87 pub proc_macro_dylib_path: Option<PathBuf>, 91 pub proc_macro_dylib_path: Option<PathBuf>,
88} 92}
@@ -141,12 +145,8 @@ impl CargoWorkspace {
141 cargo_toml: &Path, 145 cargo_toml: &Path,
142 cargo_features: &CargoConfig, 146 cargo_features: &CargoConfig,
143 ) -> Result<CargoWorkspace> { 147 ) -> Result<CargoWorkspace> {
144 let _ = Command::new(cargo_binary())
145 .arg("--version")
146 .output()
147 .context("failed to run `cargo --version`, is `cargo` in PATH?")?;
148
149 let mut meta = MetadataCommand::new(); 148 let mut meta = MetadataCommand::new();
149 meta.cargo_path(ra_toolchain::cargo());
150 meta.manifest_path(cargo_toml); 150 meta.manifest_path(cargo_toml);
151 if cargo_features.all_features { 151 if cargo_features.all_features {
152 meta.features(CargoOpt::AllFeatures); 152 meta.features(CargoOpt::AllFeatures);
@@ -160,15 +160,20 @@ impl CargoWorkspace {
160 if let Some(parent) = cargo_toml.parent() { 160 if let Some(parent) = cargo_toml.parent() {
161 meta.current_dir(parent); 161 meta.current_dir(parent);
162 } 162 }
163 if let Some(target) = cargo_features.target.as_ref() {
164 meta.other_options(vec![String::from("--filter-platform"), target.clone()]);
165 }
163 let meta = meta.exec().with_context(|| { 166 let meta = meta.exec().with_context(|| {
164 format!("Failed to run `cargo metadata --manifest-path {}`", cargo_toml.display()) 167 format!("Failed to run `cargo metadata --manifest-path {}`", cargo_toml.display())
165 })?; 168 })?;
166 169
167 let mut out_dir_by_id = FxHashMap::default(); 170 let mut out_dir_by_id = FxHashMap::default();
171 let mut cfgs = FxHashMap::default();
168 let mut proc_macro_dylib_paths = FxHashMap::default(); 172 let mut proc_macro_dylib_paths = FxHashMap::default();
169 if cargo_features.load_out_dirs_from_check { 173 if cargo_features.load_out_dirs_from_check {
170 let resources = load_extern_resources(cargo_toml, cargo_features)?; 174 let resources = load_extern_resources(cargo_toml, cargo_features)?;
171 out_dir_by_id = resources.out_dirs; 175 out_dir_by_id = resources.out_dirs;
176 cfgs = resources.cfgs;
172 proc_macro_dylib_paths = resources.proc_dylib_paths; 177 proc_macro_dylib_paths = resources.proc_dylib_paths;
173 } 178 }
174 179
@@ -194,6 +199,7 @@ impl CargoWorkspace {
194 edition, 199 edition,
195 dependencies: Vec::new(), 200 dependencies: Vec::new(),
196 features: Vec::new(), 201 features: Vec::new(),
202 cfgs: cfgs.get(&id).cloned().unwrap_or_default(),
197 out_dir: out_dir_by_id.get(&id).cloned(), 203 out_dir: out_dir_by_id.get(&id).cloned(),
198 proc_macro_dylib_path: proc_macro_dylib_paths.get(&id).cloned(), 204 proc_macro_dylib_path: proc_macro_dylib_paths.get(&id).cloned(),
199 }); 205 });
@@ -275,13 +281,14 @@ impl CargoWorkspace {
275pub struct ExternResources { 281pub struct ExternResources {
276 out_dirs: FxHashMap<PackageId, PathBuf>, 282 out_dirs: FxHashMap<PackageId, PathBuf>,
277 proc_dylib_paths: FxHashMap<PackageId, PathBuf>, 283 proc_dylib_paths: FxHashMap<PackageId, PathBuf>,
284 cfgs: FxHashMap<PackageId, Vec<String>>,
278} 285}
279 286
280pub fn load_extern_resources( 287pub fn load_extern_resources(
281 cargo_toml: &Path, 288 cargo_toml: &Path,
282 cargo_features: &CargoConfig, 289 cargo_features: &CargoConfig,
283) -> Result<ExternResources> { 290) -> Result<ExternResources> {
284 let mut cmd = Command::new(cargo_binary()); 291 let mut cmd = Command::new(ra_toolchain::cargo());
285 cmd.args(&["check", "--message-format=json", "--manifest-path"]).arg(cargo_toml); 292 cmd.args(&["check", "--message-format=json", "--manifest-path"]).arg(cargo_toml);
286 if cargo_features.all_features { 293 if cargo_features.all_features {
287 cmd.arg("--all-features"); 294 cmd.arg("--all-features");
@@ -297,13 +304,13 @@ pub fn load_extern_resources(
297 304
298 let mut res = ExternResources::default(); 305 let mut res = ExternResources::default();
299 306
300 for message in cargo_metadata::parse_messages(output.stdout.as_slice()) { 307 for message in cargo_metadata::Message::parse_stream(output.stdout.as_slice()) {
301 if let Ok(message) = message { 308 if let Ok(message) = message {
302 match message { 309 match message {
303 Message::BuildScriptExecuted(BuildScript { package_id, out_dir, .. }) => { 310 Message::BuildScriptExecuted(BuildScript { package_id, out_dir, cfgs, .. }) => {
304 res.out_dirs.insert(package_id, out_dir); 311 res.out_dirs.insert(package_id.clone(), out_dir);
312 res.cfgs.insert(package_id, cfgs);
305 } 313 }
306
307 Message::CompilerArtifact(message) => { 314 Message::CompilerArtifact(message) => {
308 if message.target.kind.contains(&"proc-macro".to_string()) { 315 if message.target.kind.contains(&"proc-macro".to_string()) {
309 let package_id = message.package_id; 316 let package_id = message.package_id;
@@ -316,6 +323,8 @@ pub fn load_extern_resources(
316 } 323 }
317 Message::CompilerMessage(_) => (), 324 Message::CompilerMessage(_) => (),
318 Message::Unknown => (), 325 Message::Unknown => (),
326 Message::BuildFinished(_) => {}
327 Message::TextLine(_) => {}
319 } 328 }
320 } 329 }
321 } 330 }
@@ -329,7 +338,3 @@ fn is_dylib(path: &Path) -> bool {
329 Some(ext) => matches!(ext.as_str(), "dll" | "dylib" | "so"), 338 Some(ext) => matches!(ext.as_str(), "dll" | "dylib" | "so"),
330 } 339 }
331} 340}
332
333fn cargo_binary() -> String {
334 env::var("CARGO").unwrap_or_else(|_| "cargo".to_string())
335}