Discover rustc_cfg through unstable cargo options
This commit is contained in:
parent
526040eea8
commit
8989fb8315
@ -201,31 +201,12 @@ pub fn from_cargo_metadata(
|
|||||||
if let Some(parent) = cargo_toml.parent() {
|
if let Some(parent) = cargo_toml.parent() {
|
||||||
meta.current_dir(parent.to_path_buf());
|
meta.current_dir(parent.to_path_buf());
|
||||||
}
|
}
|
||||||
let target = if let Some(target) = config.target.as_ref() {
|
let target = if let Some(target) = &config.target {
|
||||||
Some(target.clone())
|
Some(target.clone())
|
||||||
|
} else if let stdout @ Some(_) = cargo_config_build_target(cargo_toml) {
|
||||||
|
stdout
|
||||||
} else {
|
} else {
|
||||||
// cargo metadata defaults to giving information for _all_ targets.
|
rustc_discover_host_triple(cargo_toml)
|
||||||
// In the absence of a preference from the user, we use the host platform.
|
|
||||||
let mut rustc = Command::new(toolchain::rustc());
|
|
||||||
rustc.current_dir(cargo_toml.parent().unwrap()).arg("-vV");
|
|
||||||
log::debug!("Discovering host platform by {:?}", rustc);
|
|
||||||
match utf8_stdout(rustc) {
|
|
||||||
Ok(stdout) => {
|
|
||||||
let field = "host: ";
|
|
||||||
let target = stdout.lines().find_map(|l| l.strip_prefix(field));
|
|
||||||
if let Some(target) = target {
|
|
||||||
Some(target.to_string())
|
|
||||||
} else {
|
|
||||||
// If we fail to resolve the host platform, it's not the end of the world.
|
|
||||||
log::info!("rustc -vV did not report host platform, got:\n{}", stdout);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
log::warn!("Failed to discover host platform: {}", e);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
meta.other_options(vec![String::from("--filter-platform"), target]);
|
meta.other_options(vec![String::from("--filter-platform"), target]);
|
||||||
@ -368,3 +349,47 @@ fn is_unique(&self, name: &str) -> bool {
|
|||||||
self.packages.iter().filter(|(_, v)| v.name == name).count() == 1
|
self.packages.iter().filter(|(_, v)| v.name == name).count() == 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rustc_discover_host_triple(cargo_toml: &AbsPath) -> Option<String> {
|
||||||
|
let mut rustc = Command::new(toolchain::rustc());
|
||||||
|
rustc.current_dir(cargo_toml.parent().unwrap()).arg("-vV");
|
||||||
|
log::debug!("Discovering host platform by {:?}", rustc);
|
||||||
|
match utf8_stdout(rustc) {
|
||||||
|
Ok(stdout) => {
|
||||||
|
let field = "host: ";
|
||||||
|
let target = stdout.lines().find_map(|l| l.strip_prefix(field));
|
||||||
|
if let Some(target) = target {
|
||||||
|
Some(target.to_string())
|
||||||
|
} else {
|
||||||
|
// If we fail to resolve the host platform, it's not the end of the world.
|
||||||
|
log::info!("rustc -vV did not report host platform, got:\n{}", stdout);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!("Failed to discover host platform: {}", e);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cargo_config_build_target(cargo_toml: &AbsPath) -> Option<String> {
|
||||||
|
let mut cargo_config = Command::new(toolchain::cargo());
|
||||||
|
cargo_config.current_dir(cargo_toml.parent().unwrap()).args(&[
|
||||||
|
"+nightly",
|
||||||
|
"-Z",
|
||||||
|
"unstable-options",
|
||||||
|
"config",
|
||||||
|
"get",
|
||||||
|
"build.target",
|
||||||
|
]);
|
||||||
|
// if successful we receive `build.target = "target-triple"`
|
||||||
|
log::debug!("Discovering cargo config target by {:?}", cargo_config);
|
||||||
|
match utf8_stdout(cargo_config) {
|
||||||
|
Ok(stdout) => stdout
|
||||||
|
.strip_prefix("build.target = \"")
|
||||||
|
.and_then(|stdout| stdout.strip_suffix('"'))
|
||||||
|
.map(ToOwned::to_owned),
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
|
use paths::AbsPath;
|
||||||
|
|
||||||
use crate::{cfg_flag::CfgFlag, utf8_stdout};
|
use crate::{cfg_flag::CfgFlag, utf8_stdout};
|
||||||
|
|
||||||
pub(crate) fn get(target: Option<&str>) -> Vec<CfgFlag> {
|
pub(crate) fn get(cargo_toml: Option<&AbsPath>, target: Option<&str>) -> Vec<CfgFlag> {
|
||||||
let _p = profile::span("rustc_cfg::get");
|
let _p = profile::span("rustc_cfg::get");
|
||||||
let mut res = Vec::with_capacity(6 * 2 + 1);
|
let mut res = Vec::with_capacity(6 * 2 + 1);
|
||||||
|
|
||||||
@ -17,12 +19,34 @@ pub(crate) fn get(target: Option<&str>) -> Vec<CfgFlag> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let rustc_cfgs = {
|
let rustc_cfgs = {
|
||||||
let mut cmd = Command::new(toolchain::rustc());
|
cargo_toml
|
||||||
cmd.args(&["--print", "cfg", "-O"]);
|
.and_then(|cargo_toml| {
|
||||||
if let Some(target) = target {
|
let mut cargo_config = Command::new(toolchain::cargo());
|
||||||
cmd.args(&["--target", target]);
|
cargo_config.current_dir(cargo_toml.parent().unwrap()).args(&[
|
||||||
}
|
"+nightly",
|
||||||
utf8_stdout(cmd)
|
"-Z",
|
||||||
|
"unstable-options",
|
||||||
|
"rustc",
|
||||||
|
"--print",
|
||||||
|
"cfg",
|
||||||
|
]);
|
||||||
|
if let Some(target) = target {
|
||||||
|
cargo_config.args(&["--target", target]);
|
||||||
|
}
|
||||||
|
utf8_stdout(cargo_config).ok()
|
||||||
|
})
|
||||||
|
.map_or_else(
|
||||||
|
|| {
|
||||||
|
// using unstable cargo features failed, fall back to using plain rustc
|
||||||
|
let mut cmd = Command::new(toolchain::rustc());
|
||||||
|
cmd.args(&["--print", "cfg", "-O"]);
|
||||||
|
if let Some(target) = target {
|
||||||
|
cmd.args(&["--target", target]);
|
||||||
|
}
|
||||||
|
utf8_stdout(cmd)
|
||||||
|
},
|
||||||
|
Ok,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
match rustc_cfgs {
|
match rustc_cfgs {
|
||||||
|
@ -143,7 +143,8 @@ pub fn load(
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let rustc_cfg = rustc_cfg::get(config.target.as_deref());
|
|
||||||
|
let rustc_cfg = rustc_cfg::get(Some(&cargo_toml), config.target.as_deref());
|
||||||
ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg }
|
ProjectWorkspace::Cargo { cargo, sysroot, rustc, rustc_cfg }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -159,7 +160,7 @@ pub fn load_inline(
|
|||||||
Some(path) => Some(Sysroot::load(path)?),
|
Some(path) => Some(Sysroot::load(path)?),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
let rustc_cfg = rustc_cfg::get(target);
|
let rustc_cfg = rustc_cfg::get(None, target);
|
||||||
Ok(ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg })
|
Ok(ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +311,7 @@ fn project_json_to_crate_graph(
|
|||||||
|
|
||||||
let target_cfgs = match krate.target.as_deref() {
|
let target_cfgs = match krate.target.as_deref() {
|
||||||
Some(target) => {
|
Some(target) => {
|
||||||
cfg_cache.entry(target).or_insert_with(|| rustc_cfg::get(Some(target)))
|
cfg_cache.entry(target).or_insert_with(|| rustc_cfg::get(None, Some(target)))
|
||||||
}
|
}
|
||||||
None => &rustc_cfg,
|
None => &rustc_cfg,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user