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() {
|
||||
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())
|
||||
} else if let stdout @ Some(_) = cargo_config_build_target(cargo_toml) {
|
||||
stdout
|
||||
} else {
|
||||
// cargo metadata defaults to giving information for _all_ targets.
|
||||
// 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
|
||||
}
|
||||
}
|
||||
rustc_discover_host_triple(cargo_toml)
|
||||
};
|
||||
if let Some(target) = 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
|
||||
}
|
||||
}
|
||||
|
||||
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 paths::AbsPath;
|
||||
|
||||
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 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 mut cmd = Command::new(toolchain::rustc());
|
||||
cmd.args(&["--print", "cfg", "-O"]);
|
||||
if let Some(target) = target {
|
||||
cmd.args(&["--target", target]);
|
||||
}
|
||||
utf8_stdout(cmd)
|
||||
cargo_toml
|
||||
.and_then(|cargo_toml| {
|
||||
let mut cargo_config = Command::new(toolchain::cargo());
|
||||
cargo_config.current_dir(cargo_toml.parent().unwrap()).args(&[
|
||||
"+nightly",
|
||||
"-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 {
|
||||
|
@ -143,7 +143,8 @@ pub fn load(
|
||||
} else {
|
||||
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 }
|
||||
}
|
||||
};
|
||||
@ -159,7 +160,7 @@ pub fn load_inline(
|
||||
Some(path) => Some(Sysroot::load(path)?),
|
||||
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 })
|
||||
}
|
||||
|
||||
@ -310,7 +311,7 @@ fn project_json_to_crate_graph(
|
||||
|
||||
let target_cfgs = match krate.target.as_deref() {
|
||||
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,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user