@@ -173,6 +173,8 @@ def download_stage0(self):
173173 if not os .path .exists (tarball ):
174174 get ("{}/{}" .format (url , filename ), tarball , verbose = self .verbose )
175175 unpack (tarball , self .bin_root (), match = "rustc" , verbose = self .verbose )
176+ self .fix_executable (self .bin_root () + "/bin/rustc" )
177+ self .fix_executable (self .bin_root () + "/bin/rustdoc" )
176178 with open (self .rustc_stamp (), 'w' ) as f :
177179 f .write (self .stage0_rustc_date ())
178180
@@ -185,9 +187,63 @@ def download_stage0(self):
185187 if not os .path .exists (tarball ):
186188 get ("{}/{}" .format (url , filename ), tarball , verbose = self .verbose )
187189 unpack (tarball , self .bin_root (), match = "cargo" , verbose = self .verbose )
190+ self .fix_executable (self .bin_root () + "/bin/cargo" )
188191 with open (self .cargo_stamp (), 'w' ) as f :
189192 f .write (self .stage0_cargo_rev ())
190193
194+ def fix_executable (self , fname ):
195+ # If we're on NixOS we need to change the path to the dynamic loader
196+
197+ default_encoding = sys .getdefaultencoding ()
198+ try :
199+ ostype = subprocess .check_output (['uname' , '-s' ]).strip ().decode (default_encoding )
200+ except (subprocess .CalledProcessError , WindowsError ):
201+ return
202+
203+ if ostype != "Linux" :
204+ return
205+
206+ if not os .path .exists ("/etc/NIXOS" ):
207+ return
208+ if os .path .exists ("/lib" ):
209+ return
210+
211+ # At this point we're pretty sure the user is running NixOS
212+ print ("info: you seem to be running NixOS. Attempting to patch " + fname )
213+
214+ try :
215+ interpreter = subprocess .check_output (["patchelf" , "--print-interpreter" , fname ])
216+ interpreter = interpreter .strip ().decode (default_encoding )
217+ except subprocess .CalledProcessError as e :
218+ print ("warning: failed to call patchelf: %s" % e )
219+ return
220+
221+ loader = interpreter .split ("/" )[- 1 ]
222+
223+ try :
224+ ldd_output = subprocess .check_output (['ldd' , '/run/current-system/sw/bin/sh' ])
225+ ldd_output = ldd_output .strip ().decode (default_encoding )
226+ except subprocess .CalledProcessError as e :
227+ print ("warning: unable to call ldd: %s" % e )
228+ return
229+
230+ for line in ldd_output .splitlines ():
231+ libname = line .split ()[0 ]
232+ if libname .endswith (loader ):
233+ loader_path = libname [:len (libname ) - len (loader )]
234+ break
235+ else :
236+ print ("warning: unable to find the path to the dynamic linker" )
237+ return
238+
239+ correct_interpreter = loader_path + loader
240+
241+ try :
242+ subprocess .check_output (["patchelf" , "--set-interpreter" , correct_interpreter , fname ])
243+ except subprocess .CalledProcessError as e :
244+ print ("warning: failed to call patchelf: %s" % e )
245+ return
246+
191247 def stage0_cargo_rev (self ):
192248 return self ._cargo_rev
193249
0 commit comments