Skip to content
This repository was archived by the owner on Mar 1, 2019. It is now read-only.

Try to get the target triple from rustc itself #160

Merged
merged 2 commits into from
Jan 12, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 41 additions & 3 deletions src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ impl AnalysisLoader for CargoAnalysisLoader {
.join("deps")
.join("save-analysis");
// FIXME sys_root_path allows to break out of 'sandbox' - is that Ok?
// FIXME libs_path and src_path both assume the default `libdir = "lib"`.
let sys_root_path = sys_root_path();
let target_triple = extract_target_triple(sys_root_path.as_path());
let libs_path = sys_root_path
Expand All @@ -108,9 +109,35 @@ impl AnalysisLoader for CargoAnalysisLoader {
}
}

fn extract_target_triple(sys_root_path: &Path) -> String {
// First try to get the triple from the rustc version output,
// otherwise fall back on the rustup-style toolchain path.
// FIXME: Both methods assume that the target is the host triple,
// which isn't the case for cross-compilation (rust-lang/rls#309).
extract_rustc_host_triple()
.unwrap_or_else(|| extract_rustup_target_triple(sys_root_path))
}

fn extract_rustc_host_triple() -> Option<String> {
let rustc = env::var("RUSTC").unwrap_or(String::from("rustc"));
let verbose_version = Command::new(rustc)
.arg("--verbose")
.arg("--version")
.output()
.ok()
.and_then(|out| String::from_utf8(out.stdout).ok())?;

// Extracts the triple from a line like `host: x86_64-unknown-linux-gnu`
verbose_version
.lines()
.find(|line| line.starts_with("host: "))
.and_then(|host| host.split_whitespace().nth(1))
.map(String::from)
}

// FIXME: This can fail when using a custom toolchain in rustup (often linked to
// `/$rust_repo/build/$target/stage2`)
fn extract_target_triple(sys_root_path: &Path) -> String {
fn extract_rustup_target_triple(sys_root_path: &Path) -> String {
// Extracts nightly-x86_64-pc-windows-msvc from
// $HOME/.rustup/toolchains/nightly-x86_64-pc-windows-msvc
let toolchain = sys_root_path
Expand Down Expand Up @@ -169,7 +196,7 @@ mod tests {
r#"C:\Users\user\.rustup\toolchains\nightly-x86_64-pc-windows-msvc"#,
);
assert_eq!(
extract_target_triple(path),
extract_rustup_target_triple(path),
String::from("x86_64-pc-windows-msvc")
);
}
Expand All @@ -180,8 +207,19 @@ mod tests {
"/home/user/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu",
);
assert_eq!(
extract_target_triple(path),
extract_rustup_target_triple(path),
String::from("x86_64-unknown-linux-gnu")
);
}

#[test]
fn target_triple() {
let sys_root_path = sys_root_path();
let target_triple = extract_target_triple(&sys_root_path);
let target_path = sys_root_path
.join("lib")
.join("rustlib")
.join(&target_triple);
assert!(target_path.is_dir(), "{:?} is not a directory!", target_path);
}
}