1212from  urllib .request  import  urlretrieve 
1313from  os  import  listdir , unlink , environ , curdir , walk 
1414from  sys  import  stdout 
15+ from  multiprocessing  import  cpu_count 
1516import  time 
1617try :
1718    from  urlparse  import  urlparse 
@@ -517,7 +518,7 @@ def unpack(self, arch):
517518                    for  entry  in  listdir (extraction_filename ):
518519                        # Previously we filtered out the .git folder, but during the build process for some recipes 
519520                        # (e.g. when version is parsed by `setuptools_scm`) that may be needed. 
520-                         shprint (sh .cp , '-Rv ' ,
521+                         shprint (sh .cp , '-R ' ,
521522                                join (extraction_filename , entry ),
522523                                directory_name )
523524                else :
@@ -830,6 +831,8 @@ def build_arch(self, arch, *extra_args):
830831            shprint (
831832                sh .Command (join (self .ctx .ndk_dir , "ndk-build" )),
832833                'V=1' ,
834+                 "-j" ,
835+                 str (cpu_count ()),
833836                'NDK_DEBUG='  +  ("1"  if  self .ctx .build_as_debuggable  else  "0" ),
834837                'APP_PLATFORM=android-'  +  str (self .ctx .ndk_api ),
835838                'APP_ABI='  +  arch .arch ,
@@ -878,6 +881,8 @@ class PythonRecipe(Recipe):
878881    hostpython_prerequisites  =  []
879882    '''List of hostpython packages required to build a recipe''' 
880883
884+     _host_recipe  =  None 
885+ 
881886    def  __init__ (self , * args , ** kwargs ):
882887        super ().__init__ (* args , ** kwargs )
883888        if  'python3'  not  in self .depends :
@@ -890,6 +895,10 @@ def __init__(self, *args, **kwargs):
890895            depends  =  list (set (depends ))
891896            self .depends  =  depends 
892897
898+     def  prebuild_arch (self , arch ):
899+         self ._host_recipe  =  Recipe .get_recipe ("hostpython3" , self .ctx )
900+         return  super ().prebuild_arch (arch )
901+ 
893902    def  clean_build (self , arch = None ):
894903        super ().clean_build (arch = arch )
895904        name  =  self .folder_name 
@@ -907,8 +916,7 @@ def clean_build(self, arch=None):
907916    def  real_hostpython_location (self ):
908917        host_name  =  'host{}' .format (self .ctx .python_recipe .name )
909918        if  host_name  ==  'hostpython3' :
910-             python_recipe  =  Recipe .get_recipe (host_name , self .ctx )
911-             return  python_recipe .python_exe 
919+             return  self ._host_recipe .python_exe 
912920        else :
913921            python_recipe  =  self .ctx .python_recipe 
914922            return  'python{}' .format (python_recipe .version )
@@ -927,14 +935,44 @@ def folder_name(self):
927935            name  =  self .name 
928936        return  name 
929937
938+     def  patch_shebang (self , _file , original_bin ):
939+         _file_des  =  open (_file , "r" )
940+ 
941+         try :
942+             data  =  _file_des .readlines ()
943+         except  UnicodeDecodeError :
944+             return 
945+ 
946+         if  "#!"  in  (line  :=  data [0 ]):
947+             if  line .split ("#!" )[- 1 ].strip () ==  original_bin :
948+                 return 
949+ 
950+             info (f"Fixing shebang for '{ _file }  )
951+             data .pop (0 )
952+             data .insert (0 , "#!"  +  original_bin  +  "\n " )
953+             _file_des .close ()
954+             _file_des  =  open (_file , "w" )
955+             _file_des .write ("" .join (data ))
956+             _file_des .close ()
957+ 
958+     def  patch_shebangs (self , path , original_bin ):
959+         # set correct shebang 
960+         for  file  in  listdir (path ):
961+             _file  =  join (path , file )
962+             self .patch_shebang (_file , original_bin )
963+ 
930964    def  get_recipe_env (self , arch = None , with_flags_in_cc = True ):
965+         if  self ._host_recipe  is  None :
966+             self ._host_recipe  =  Recipe .get_recipe ("hostpython3" , self .ctx )
967+ 
931968        env  =  super ().get_recipe_env (arch , with_flags_in_cc )
932-         env ['PYTHONNOUSERSITE' ] =  '1' 
933969        # Set the LANG, this isn't usually important but is a better default 
934970        # as it occasionally matters how Python e.g. reads files 
935971        env ['LANG' ] =  "en_GB.UTF-8" 
936972        # Binaries made by packages installed by pip 
937-         env ["PATH" ] =  join (self .hostpython_site_dir , "bin" ) +  ":"  +  env ["PATH" ]
973+         env ["PATH" ] =  self ._host_recipe .site_bin  +  ":"  +  env ["PATH" ]
974+         host_env  =  self .get_hostrecipe_env ()
975+         env ['PYTHONPATH' ] =  host_env ["PYTHONPATH" ]
938976
939977        if  not  self .call_hostpython_via_targetpython :
940978            env ['CFLAGS' ] +=  ' -I{}' .format (
@@ -945,18 +983,6 @@ def get_recipe_env(self, arch=None, with_flags_in_cc=True):
945983                self .ctx .python_recipe .link_version ,
946984            )
947985
948-             hppath  =  []
949-             hppath .append (join (dirname (self .hostpython_location ), 'Lib' ))
950-             hppath .append (join (hppath [0 ], 'site-packages' ))
951-             builddir  =  join (dirname (self .hostpython_location ), 'build' )
952-             if  exists (builddir ):
953-                 hppath  +=  [join (builddir , d ) for  d  in  listdir (builddir )
954-                            if  isdir (join (builddir , d ))]
955-             if  len (hppath ) >  0 :
956-                 if  'PYTHONPATH'  in  env :
957-                     env ['PYTHONPATH' ] =  ':' .join (hppath  +  [env ['PYTHONPATH' ]])
958-                 else :
959-                     env ['PYTHONPATH' ] =  ':' .join (hppath )
960986        return  env 
961987
962988    def  should_build (self , arch ):
@@ -993,25 +1019,36 @@ def install_python_package(self, arch, name=None, env=None, is_dir=True):
9931019                    '--install-lib=.' ,
9941020                    _env = hpenv , * self .setup_extra_args )
9951021
996-             # If asked, also install in the hostpython build dir 
997-             if  self .install_in_hostpython :
998-                 self .install_hostpython_package (arch )
1022+             if  isfile ("setup.py" ):
1023+                 shprint (hostpython , 'setup.py' , 'install' , '-O2' ,
1024+                         '--root={}' .format (self .ctx .get_python_install_dir (arch .arch )),
1025+                         '--install-lib=.' ,
1026+                         _env = hpenv , * self .setup_extra_args )
1027+ 
1028+                 # If asked, also install in the hostpython build dir 
1029+                 if  self .install_in_hostpython :
1030+                     self .install_hostpython_package (arch )
1031+             else :
1032+                 warning ("`PythonRecipe.install_python_package` called without `setup.py` file!" )
9991033
1000-     def  get_hostrecipe_env (self ,  arch ):
1034+     def  get_hostrecipe_env (self ):
10011035        env  =  environ .copy ()
1002-         env ['PYTHONPATH' ] =  self .hostpython_site_dir 
1036+         _python_path  =  self ._host_recipe .get_path_to_python ()
1037+         env ['PYTHONPATH' ] =  self ._host_recipe .site_dir  +  ":"  +  join (
1038+             _python_path , "Modules" ) +  ":"  +  glob .glob (join (_python_path , "build" , "lib*" ))[0 ]
10031039        return  env 
10041040
10051041    @property  
10061042    def  hostpython_site_dir (self ):
10071043        return  join (dirname (self .real_hostpython_location ), 'Lib' , 'site-packages' )
10081044
10091045    def  install_hostpython_package (self , arch ):
1010-         env  =  self .get_hostrecipe_env (arch )
1046+         env  =  self .get_hostrecipe_env ()
10111047        real_hostpython  =  sh .Command (self .real_hostpython_location )
10121048        shprint (real_hostpython , 'setup.py' , 'install' , '-O2' ,
10131049                '--root={}' .format (dirname (self .real_hostpython_location )),
10141050                '--install-lib=Lib/site-packages' ,
1051+                 '--root={}' .format (self ._host_recipe .site_root ),
10151052                _env = env , * self .setup_extra_args )
10161053
10171054    @property  
@@ -1029,15 +1066,17 @@ def install_hostpython_prerequisites(self, packages=None, force_upgrade=True):
10291066        pip_options  =  [
10301067            "install" ,
10311068            * packages ,
1032-             "--target" , self .hostpython_site_dir , "--python-version" ,
1069+             "--target" , self ._host_recipe . site_dir , "--python-version" ,
10331070            self .ctx .python_recipe .version ,
10341071            # Don't use sources, instead wheels 
10351072            "--only-binary=:all:" ,
10361073        ]
10371074        if  force_upgrade :
10381075            pip_options .append ("--upgrade" )
10391076        # Use system's pip 
1040-         shprint (sh .pip , * pip_options )
1077+         pip_env  =  self .get_hostrecipe_env ()
1078+         pip_env ["HOME" ] =  "/tmp" 
1079+         shprint (sh .Command (self .real_hostpython_location ), "-m" , "pip" , * pip_options , _env = pip_env )
10411080
10421081    def  restore_hostpython_prerequisites (self , packages ):
10431082        _packages  =  []
@@ -1076,7 +1115,7 @@ def build_compiled_components(self, arch):
10761115                    env ['STRIP' ], '{}' , ';' , _env = env )
10771116
10781117    def  install_hostpython_package (self , arch ):
1079-         env  =  self .get_hostrecipe_env (arch )
1118+         env  =  self .get_hostrecipe_env ()
10801119        self .rebuild_compiled_components (arch , env )
10811120        super ().install_hostpython_package (arch )
10821121
@@ -1231,7 +1270,7 @@ def get_recipe_env(self, arch, **kwargs):
12311270        return  env 
12321271
12331272    def  get_wheel_platform_tag (self , arch ):
1234-         return  "android_"  +  {
1273+         return  f "android_{ self . ctx . ndk_api } _ "+  {
12351274            "armeabi-v7a" : "arm" ,
12361275            "arm64-v8a" : "aarch64" ,
12371276            "x86_64" : "x86_64" ,
@@ -1268,6 +1307,9 @@ def build_arch(self, arch):
12681307        self .install_hostpython_prerequisites (
12691308            packages = ["build[virtualenv]" , "pip" ] +  self .hostpython_prerequisites 
12701309        )
1310+         python_bin_dir  =  join (self ._host_recipe .site_dir , "bin" )
1311+         self .patch_shebangs (python_bin_dir , self .real_hostpython_location )
1312+ 
12711313        build_dir  =  self .get_build_dir (arch .arch )
12721314        env  =  self .get_recipe_env (arch , with_flags_in_cc = True )
12731315        # make build dir separately 
0 commit comments