2727 binding_features ,
2828 get_rust_target_info ,
2929 get_rust_target_list ,
30+ split_platform_and_extension ,
3031)
3132
3233
@@ -65,6 +66,7 @@ def initialize_options(self) -> None:
6566 self .build_temp = None
6667 self .plat_name = None
6768 self .target = os .getenv ("CARGO_BUILD_TARGET" )
69+ self .cargo = os .getenv ("CARGO" , "cargo" )
6870
6971 def finalize_options (self ) -> None :
7072 super ().finalize_options ()
@@ -246,7 +248,7 @@ def build_extension(
246248
247249 if executable :
248250 args = (
249- [" cargo" , "build" , "--manifest-path" , ext .path ]
251+ [self . cargo , "build" , "--manifest-path" , ext .path ]
250252 + feature_args
251253 + target_args
252254 + list (ext .args or [])
@@ -262,7 +264,7 @@ def build_extension(
262264
263265 else :
264266 args = (
265- [" cargo" , "rustc" , "--lib" , "--manifest-path" , ext .path ]
267+ [self . cargo , "rustc" , "--lib" , "--manifest-path" , ext .path ]
266268 + feature_args
267269 + target_args
268270 + list (ext .args or [])
@@ -396,13 +398,13 @@ def install_extension(
396398
397399 if executable :
398400 ext_path = build_ext .get_ext_fullpath (module_name )
399- # remove .so extension
400- ext_path , _ = os .path .splitext (ext_path )
401- # remove python3 extension (i.e. cpython-36m)
402- ext_path , _ = os .path .splitext (ext_path )
401+ # remove extensions
402+ ext_path , _ , _ = split_platform_and_extension (ext_path )
403403
404404 # Add expected extension
405- ext_path += sysconfig .get_config_var ("EXE" )
405+ exe = sysconfig .get_config_var ("EXE" )
406+ if exe is not None :
407+ ext_path += exe
406408
407409 os .makedirs (os .path .dirname (ext_path ), exist_ok = True )
408410 ext .install_script (module_name .split ("." )[- 1 ], ext_path )
@@ -434,9 +436,10 @@ def install_extension(
434436 os .chmod (ext_path , mode )
435437
436438 def get_dylib_ext_path (self , ext : RustExtension , target_fname : str ) -> str :
439+ assert self .plat_name is not None
437440 build_ext = cast (CommandBuildExt , self .get_finalized_command ("build_ext" ))
438441
439- filename : str = build_ext .get_ext_fullpath (target_fname )
442+ ext_path : str = build_ext .get_ext_fullpath (target_fname )
440443
441444 if (ext .py_limited_api == "auto" and self ._py_limited_api ()) or (
442445 ext .py_limited_api
@@ -445,9 +448,34 @@ def get_dylib_ext_path(self, ext: RustExtension, target_fname: str) -> str:
445448 if abi3_suffix is not None :
446449 so_ext = get_config_var ("EXT_SUFFIX" )
447450 assert isinstance (so_ext , str )
448- filename = filename [: - len (so_ext )] + get_abi3_suffix ()
449-
450- return filename
451+ ext_path = ext_path [: - len (so_ext )] + get_abi3_suffix ()
452+
453+ if ".abi3." in ext_path :
454+ return ext_path
455+ # Examples: linux_x86_64, linux_i686, manylinux2014_aarch64, manylinux_2_24_armv7l
456+ plat_name = self .plat_name .lower ().replace ("-" , "_" ).replace ("." , "_" )
457+ if not plat_name .startswith (("linux" , "manylinux" )):
458+ return ext_path
459+
460+ arch_parts = []
461+ arch_found = False
462+ for item in plat_name .split ("_" ):
463+ if item .startswith (("linux" , "manylinux" )):
464+ continue
465+ if item .isdigit () and not arch_found :
466+ # manylinux_2_24_armv7l arch should be armv7l
467+ continue
468+ arch_found = True
469+ arch_parts .append (item )
470+ target_arch = "_" .join (arch_parts )
471+ host_platform = sysconfig .get_platform ()
472+ host_arch = host_platform .rsplit ("-" , 1 )[1 ]
473+ # Remove incorrect platform tag if we are cross compiling
474+ if target_arch and host_arch != target_arch :
475+ ext_path , _ , extension = split_platform_and_extension (ext_path )
476+ # rust.so, removed platform tag
477+ ext_path += extension
478+ return ext_path
451479
452480 def _py_limited_api (self ) -> PyLimitedApi :
453481 bdist_wheel = self .distribution .get_command_obj ("bdist_wheel" , create = False )
0 commit comments