@@ -793,6 +793,32 @@ fn handle_cffi_call_result(
793793 }
794794}
795795
796+ // Extract the shared object from a AIX big library archive
797+ fn unpack_big_archive (
798+ target : & Target ,
799+ artifact : & Path ,
800+ temp_dir_path : & Path ,
801+ ) -> Result < PathBuf > {
802+ // Newer rust generates archived dylibs on AIX, as shared
803+ // libraries are typically archived on the platform.
804+ if target. cross_compiling ( ) {
805+ bail ! ( "can't unpack big archive format while cross_compiling" )
806+ }
807+ debug ! ( "Unpacking archive {}" , artifact. display( ) ) ;
808+ let mut ar_command = Command :: new ( "ar" ) ;
809+ ar_command
810+ . current_dir ( temp_dir_path)
811+ . arg ( "-X64" )
812+ . arg ( "x" )
813+ . arg ( artifact) ;
814+ let status = ar_command. status ( ) . expect ( "Failed to run ar" ) ;
815+ if !status. success ( ) {
816+ bail ! ( r#"ar finished with "{}": `{:?}`"# , status, ar_command, )
817+ }
818+ let unpacked_artifact = temp_dir_path. join ( artifact. with_extension ( "so" ) . file_name ( ) . unwrap ( ) ) ;
819+ Ok ( unpacked_artifact)
820+ }
821+
796822/// Copies the shared library into the module, which is the only extra file needed with bindings
797823#[ allow( clippy:: too_many_arguments) ]
798824#[ instrument( skip_all) ]
@@ -825,23 +851,32 @@ pub fn write_bindings_module(
825851 python_interpreter. get_library_name ( ext_name)
826852 } ;
827853
854+ let artifact_is_big_ar = target. is_aix ( ) && artifact. extension ( ) . unwrap_or ( OsStr :: new ( " " ) ) == OsStr :: new ( "a" ) ;
855+ let temp_dir= if artifact_is_big_ar { Some ( tempfile:: tempdir ( ) ?) } else { None } ;
856+ let artifact_buff = if artifact_is_big_ar { Some ( unpack_big_archive ( target, artifact, temp_dir. as_ref ( ) . unwrap ( ) . path ( ) ) ?) } else { None } ;
857+ let artifact = if artifact_is_big_ar { artifact_buff. as_ref ( ) . unwrap ( ) } else { artifact } ;
858+
828859 if !editable {
829860 write_python_part ( writer, project_layout, pyproject_toml)
830861 . context ( "Failed to add the python module to the package" ) ?;
831862 }
832863 if let Some ( python_module) = & project_layout. python_module {
833864 if editable {
834- let target = project_layout. rust_module . join ( & so_filename) ;
865+ let target_file = project_layout. rust_module . join ( & so_filename) ;
835866 // Remove existing so file to avoid triggering SIGSEV in running process
836867 // See https://github.com/PyO3/maturin/issues/758
837- debug ! ( "Removing {}" , target . display( ) ) ;
838- let _ = fs:: remove_file ( & target ) ;
868+ debug ! ( "Removing {}" , target_file . display( ) ) ;
869+ let _ = fs:: remove_file ( & target_file ) ;
839870
840- debug ! ( "Copying {} to {}" , artifact. display( ) , target. display( ) ) ;
841- fs:: copy ( artifact, & target) . context ( format ! (
871+ debug ! (
872+ "Copying {} to {}" ,
873+ artifact. display( ) ,
874+ target_file. display( )
875+ ) ;
876+ fs:: copy ( artifact, & target_file) . context ( format ! (
842877 "Failed to copy {} to {}" ,
843878 artifact. display( ) ,
844- target . display( )
879+ target_file . display( )
845880 ) ) ?;
846881 } else {
847882 let relative = project_layout
0 commit comments