@@ -908,7 +908,6 @@ impl<'a> Builder<'a> {
908
908
)
909
909
. env ( "RUSTC_SYSROOT" , & sysroot)
910
910
. env ( "RUSTC_LIBDIR" , & libdir)
911
- . env ( "RUSTC_RPATH" , self . config . rust_rpath . to_string ( ) )
912
911
. env ( "RUSTDOC" , self . out . join ( "bootstrap/debug/rustdoc" ) )
913
912
. env (
914
913
"RUSTDOC_REAL" ,
@@ -921,6 +920,54 @@ impl<'a> Builder<'a> {
921
920
. env ( "RUSTC_ERROR_METADATA_DST" , self . extended_error_dir ( ) )
922
921
. env ( "RUSTC_BREAK_ON_ICE" , "1" ) ;
923
922
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
+
924
971
if let Some ( host_linker) = self . linker ( compiler. host ) {
925
972
cargo. env ( "RUSTC_HOST_LINKER" , host_linker) ;
926
973
}
0 commit comments