aboutsummaryrefslogtreecommitdiff
path: root/crates/project_model/src/cargo_workspace.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/project_model/src/cargo_workspace.rs')
-rw-r--r--crates/project_model/src/cargo_workspace.rs67
1 files changed, 44 insertions, 23 deletions
diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs
index bc6e20341..b18699b77 100644
--- a/crates/project_model/src/cargo_workspace.rs
+++ b/crates/project_model/src/cargo_workspace.rs
@@ -201,31 +201,12 @@ impl CargoWorkspace {
201 if let Some(parent) = cargo_toml.parent() { 201 if let Some(parent) = cargo_toml.parent() {
202 meta.current_dir(parent.to_path_buf()); 202 meta.current_dir(parent.to_path_buf());
203 } 203 }
204 let target = if let Some(target) = config.target.as_ref() { 204 let target = if let Some(target) = &config.target {
205 Some(target.clone()) 205 Some(target.clone())
206 } else if let stdout @ Some(_) = cargo_config_build_target(cargo_toml) {
207 stdout
206 } else { 208 } else {
207 // cargo metadata defaults to giving information for _all_ targets. 209 rustc_discover_host_triple(cargo_toml)
208 // In the absence of a preference from the user, we use the host platform.
209 let mut rustc = Command::new(toolchain::rustc());
210 rustc.current_dir(cargo_toml.parent().unwrap()).arg("-vV");
211 log::debug!("Discovering host platform by {:?}", rustc);
212 match utf8_stdout(rustc) {
213 Ok(stdout) => {
214 let field = "host: ";
215 let target = stdout.lines().find_map(|l| l.strip_prefix(field));
216 if let Some(target) = target {
217 Some(target.to_string())
218 } else {
219 // If we fail to resolve the host platform, it's not the end of the world.
220 log::info!("rustc -vV did not report host platform, got:\n{}", stdout);
221 None
222 }
223 }
224 Err(e) => {
225 log::warn!("Failed to discover host platform: {}", e);
226 None
227 }
228 }
229 }; 210 };
230 if let Some(target) = target { 211 if let Some(target) = target {
231 meta.other_options(vec![String::from("--filter-platform"), target]); 212 meta.other_options(vec![String::from("--filter-platform"), target]);
@@ -368,3 +349,43 @@ impl CargoWorkspace {
368 self.packages.iter().filter(|(_, v)| v.name == name).count() == 1 349 self.packages.iter().filter(|(_, v)| v.name == name).count() == 1
369 } 350 }
370} 351}
352
353fn rustc_discover_host_triple(cargo_toml: &AbsPath) -> Option<String> {
354 let mut rustc = Command::new(toolchain::rustc());
355 rustc.current_dir(cargo_toml.parent().unwrap()).arg("-vV");
356 log::debug!("Discovering host platform by {:?}", rustc);
357 match utf8_stdout(rustc) {
358 Ok(stdout) => {
359 let field = "host: ";
360 let target = stdout.lines().find_map(|l| l.strip_prefix(field));
361 if let Some(target) = target {
362 Some(target.to_string())
363 } else {
364 // If we fail to resolve the host platform, it's not the end of the world.
365 log::info!("rustc -vV did not report host platform, got:\n{}", stdout);
366 None
367 }
368 }
369 Err(e) => {
370 log::warn!("Failed to discover host platform: {}", e);
371 None
372 }
373 }
374}
375
376fn cargo_config_build_target(cargo_toml: &AbsPath) -> Option<String> {
377 let mut cargo_config = Command::new(toolchain::cargo());
378 cargo_config
379 .current_dir(cargo_toml.parent().unwrap())
380 .args(&["-Z", "unstable-options", "config", "get", "build.target"])
381 .env("RUSTC_BOOTSTRAP", "1");
382 // if successful we receive `build.target = "target-triple"`
383 log::debug!("Discovering cargo config target by {:?}", cargo_config);
384 match utf8_stdout(cargo_config) {
385 Ok(stdout) => stdout
386 .strip_prefix("build.target = \"")
387 .and_then(|stdout| stdout.strip_suffix('"'))
388 .map(ToOwned::to_owned),
389 Err(_) => None,
390 }
391}