@@ -908,7 +908,6 @@ impl<'a> Builder<'a> {
908908 )
909909 . env ( "RUSTC_SYSROOT" , & sysroot)
910910 . env ( "RUSTC_LIBDIR" , & libdir)
911- . env ( "RUSTC_RPATH" , self . config . rust_rpath . to_string ( ) )
912911 . env ( "RUSTDOC" , self . out . join ( "bootstrap/debug/rustdoc" ) )
913912 . env (
914913 "RUSTDOC_REAL" ,
@@ -921,6 +920,54 @@ impl<'a> Builder<'a> {
921920 . env ( "RUSTC_ERROR_METADATA_DST" , self . extended_error_dir ( ) )
922921 . env ( "RUSTC_BREAK_ON_ICE" , "1" ) ;
923922
923+ // Dealing with rpath here is a little special, so let's go into some
924+ // detail. First off, `-rpath` is a linker option on Unix platforms
925+ // which adds to the runtime dynamic loader path when looking for
926+ // dynamic libraries. We use this by default on Unix platforms to ensure
927+ // that our nightlies behave the same on Windows, that is they work out
928+ // of the box. This can be disabled, of course, but basically that's why
929+ // we're gated on RUSTC_RPATH here.
930+ //
931+ // Ok, so the astute might be wondering "why isn't `-C rpath` used
932+ // here?" and that is indeed a good question to task. This codegen
933+ // option is the compiler's current interface to generating an rpath.
934+ // Unfortunately it doesn't quite suffice for us. The flag currently
935+ // takes no value as an argument, so the compiler calculates what it
936+ // should pass to the linker as `-rpath`. This unfortunately is based on
937+ // the **compile time** directory structure which when building with
938+ // Cargo will be very different than the runtime directory structure.
939+ //
940+ // All that's a really long winded way of saying that if we use
941+ // `-Crpath` then the executables generated have the wrong rpath of
942+ // something like `$ORIGIN/deps` when in fact the way we distribute
943+ // rustc requires the rpath to be `$ORIGIN/../lib`.
944+ //
945+ // So, all in all, to set up the correct rpath we pass the linker
946+ // argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
947+ // fun to pass a flag to a tool to pass a flag to pass a flag to a tool
948+ // to change a flag in a binary?
949+ if self . config . rust_rpath {
950+ let rpath = if target. contains ( "apple" ) {
951+
952+ // Note that we need to take one extra step on macOS to also pass
953+ // `-Wl,-instal_name,@rpath/...` to get things to work right. To
954+ // do that we pass a weird flag to the compiler to get it to do
955+ // so. Note that this is definitely a hack, and we should likely
956+ // flesh out rpath support more fully in the future.
957+ rustflags. arg ( "-Zosx-rpath-install-name" ) ;
958+ Some ( "-Wl,-rpath,@loader_path/../lib" )
959+ } else if !target. contains ( "windows" ) &&
960+ !target. contains ( "wasm32" ) &&
961+ !target. contains ( "fuchsia" ) {
962+ Some ( "-Wl,-rpath,$ORIGIN/../lib" )
963+ } else {
964+ None
965+ } ;
966+ if let Some ( rpath) = rpath {
967+ rustflags. arg ( & format ! ( "-Clink-args={}" , rpath) ) ;
968+ }
969+ }
970+
924971 if let Some ( host_linker) = self . linker ( compiler. host ) {
925972 cargo. env ( "RUSTC_HOST_LINKER" , host_linker) ;
926973 }
0 commit comments