Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustbuild: Fix --enable-rpath usage #32903

Merged
merged 1 commit into from
Apr 20, 2016
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
73 changes: 55 additions & 18 deletions src/bootstrap/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,15 @@ fn main() {
let args = env::args_os().skip(1).collect::<Vec<_>>();
// Detect whether or not we're a build script depending on whether --target
// is passed (a bit janky...)
let is_build_script = args.iter()
.position(|i| i.to_str() == Some("--target"))
.is_none();
let target = args.windows(2).find(|w| &*w[0] == "--target")
.and_then(|w| w[1].to_str());

// Build scripts always use the snapshot compiler which is guaranteed to be
// able to produce an executable, whereas intermediate compilers may not
// have the standard library built yet and may not be able to produce an
// executable. Otherwise we just use the standard compiler we're
// bootstrapping with.
let rustc = if is_build_script {
let rustc = if target.is_none() {
env::var_os("RUSTC_SNAPSHOT").unwrap()
} else {
env::var_os("RUSTC_REAL").unwrap()
Expand All @@ -55,7 +54,7 @@ fn main() {
cmd.args(&args)
.arg("--cfg").arg(format!("stage{}", env::var("RUSTC_STAGE").unwrap()));

if is_build_script {
if target.is_none() {
// Build scripts are always built with the snapshot compiler, so we need
// to be sure to set up the right path information for the OS dynamic
// linker to find the libraries in question.
Expand Down Expand Up @@ -85,19 +84,57 @@ fn main() {

// Set various options from config.toml to configure how we're building
// code.
if env::var("RUSTC_DEBUGINFO") == Ok("true".to_string()) {
cmd.arg("-g");
}
if env::var("RUSTC_RPATH") == Ok("true".to_string()) {
cmd.arg("-Crpath");
}
let debug_assertions = match env::var("RUSTC_DEBUG_ASSERTIONS") {
Ok(s) => if s == "true" {"y"} else {"n"},
Err(..) => "n",
};
cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions));
if let Ok(s) = env::var("RUSTC_CODEGEN_UNITS") {
cmd.arg("-C").arg(format!("codegen-units={}", s));
if let Some(target) = target {
if env::var("RUSTC_DEBUGINFO") == Ok("true".to_string()) {
cmd.arg("-g");
}
let debug_assertions = match env::var("RUSTC_DEBUG_ASSERTIONS") {
Ok(s) => if s == "true" {"y"} else {"n"},
Err(..) => "n",
};
cmd.arg("-C").arg(format!("debug-assertions={}", debug_assertions));
if let Ok(s) = env::var("RUSTC_CODEGEN_UNITS") {
cmd.arg("-C").arg(format!("codegen-units={}", s));
}

// Dealing with rpath here is a little special, so let's go into some
// detail. First off, `-rpath` is a linker option on Unix platforms
// which adds to the runtime dynamic loader path when looking for
// dynamic libraries. We use this by default on Unix platforms to ensure
// that our nightlies behave the same on Windows, that is they work out
// of the box. This can be disabled, of course, but basically that's why
// we're gated on RUSTC_RPATH here.
//
// Ok, so the astute might be wondering "why isn't `-C rpath` used
// here?" and that is indeed a good question to task. This codegen
// option is the compiler's current interface to generating an rpath.
// Unfortunately it doesn't quite suffice for us. The flag currently
// takes no value as an argument, so the compiler calculates what it
// should pass to the linker as `-rpath`. This unfortunately is based on
// the **compile time** directory structure which when building with
// Cargo will be very different than the runtime directory structure.
//
// All that's a really long winded way of saying that if we use
// `-Crpath` then the executables generated have the wrong rpath of
// something like `$ORIGIN/deps` when in fact the way we distribute
// rustc requires the rpath to be `$ORIGIN/../lib`.
//
// So, all in all, to set up the correct rpath we pass the linker
// argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
// fun to pass a flag to a tool to pass a flag to pass a flag to a tool
// to change a flag in a binary?
if env::var("RUSTC_RPATH") == Ok("true".to_string()) {
let rpath = if target.contains("apple") {
Some("-Wl,-rpath,@loader_path/../lib")
} else if !target.contains("windows") {
Some("-Wl,-rpath,$ORIGIN/../lib")
} else {
None
};
if let Some(rpath) = rpath {
cmd.arg("-C").arg(format!("link-args={}", rpath));
}
}
}

// Actually run the compiler!
Expand Down