@@ -180,6 +180,10 @@ def run_for_extension(self, ext: RustExtension):
180
180
if ext .native :
181
181
rustflags += " -C target-cpu=native"
182
182
183
+ if not executable and sys .platform == "darwin" :
184
+ ext_basename = os .path .basename (self .get_dylib_ext_path (ext , ext .name ))
185
+ rustflags += f" -C link-args=-Wl,-install_name,@rpath/{ ext_basename } "
186
+
183
187
if rustflags :
184
188
env ["RUSTFLAGS" ] = (env .get ("RUSTFLAGS" , "" ) + " " + rustflags ).strip ()
185
189
@@ -281,16 +285,7 @@ def run_for_extension(self, ext: RustExtension):
281
285
282
286
ext .install_script (ext_path )
283
287
else :
284
- # Technically it's supposed to contain a
285
- # `setuptools.Extension`, but in practice the only attribute it
286
- # checks is `ext.py_limited_api`.
287
- modpath = target_fname .split ('.' )[- 1 ]
288
- assert modpath not in build_ext .ext_map
289
- build_ext .ext_map [modpath ] = ext
290
- try :
291
- ext_path = build_ext .get_ext_fullpath (target_fname )
292
- finally :
293
- del build_ext .ext_map [modpath ]
288
+ ext_path = self .get_dylib_ext_path (ext , target_fname )
294
289
295
290
os .makedirs (os .path .dirname (ext_path ), exist_ok = True )
296
291
shutil .copyfile (dylib_path , ext_path )
@@ -307,11 +302,24 @@ def run_for_extension(self, ext: RustExtension):
307
302
args .append (ext_path )
308
303
try :
309
304
output = subprocess .check_output (args , env = env )
310
- except subprocess .CalledProcessError as e :
305
+ except subprocess .CalledProcessError :
311
306
pass
312
307
313
308
# executables, win32(cygwin)-dll's, and shared libraries on
314
309
# Unix-like operating systems need X bits
315
310
mode = os .stat (ext_path ).st_mode
316
311
mode |= (mode & 0o444 ) >> 2 # copy R bits to X
317
312
os .chmod (ext_path , mode )
313
+
314
+ def get_dylib_ext_path (self , ext , target_fname ):
315
+ build_ext = self .get_finalized_command ("build_ext" )
316
+ # Technically it's supposed to contain a
317
+ # `setuptools.Extension`, but in practice the only attribute it
318
+ # checks is `ext.py_limited_api`.
319
+ modpath = target_fname .split ('.' )[- 1 ]
320
+ assert modpath not in build_ext .ext_map
321
+ build_ext .ext_map [modpath ] = ext
322
+ try :
323
+ return build_ext .get_ext_fullpath (target_fname )
324
+ finally :
325
+ del build_ext .ext_map [modpath ]
0 commit comments