mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-15 00:13:02 +00:00
Auto merge of #32903 - alexcrichton:fix-rpath, r=brson
rustbuild: Fix --enable-rpath usage This commit fixes the `--enable-rpath` configure flag in rustbuild to work despite the compile-time directories being different than the runtime directories. This unfortunately means that we can't use `-C rpath` out of the box but hopefully the portability story here isn't too bad as `src/librustc_back/rpath.rs` isn't *too* complicated. Closes #32886
This commit is contained in:
commit
3dd88f60de
@ -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()
|
||||
@ -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.
|
||||
@ -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!
|
||||
|
Loading…
Reference in New Issue
Block a user