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