distutils usage, as is not available anymore on Python 3.12 (#2912)
from os import environfrom os.path import joinfrom multiprocessing import cpu_countimport shutilfrom pythonforandroid.recipe import Recipefrom pythonforandroid.util import BuildInterruptingException, build_platformclass Arch:command_prefix = None'''The prefix for NDK commands such as gcc.'''arch = ""'''Name of the arch such as: `armeabi-v7a`, `arm64-v8a`, `x86`...'''arch_cflags = []'''Specific arch `cflags`, expect to be overwrote in subclass if needed.'''common_cflags = ['-target {target}','-fomit-frame-pointer']common_cppflags = ['-DANDROID','-I{ctx.ndk.sysroot_include_dir}','-I{python_includes}',]common_ldflags = ['-L{ctx_libs_dir}']common_ldlibs = ['-lm']common_ldshared = ['-pthread','-shared','-Wl,-O1','-Wl,-Bsymbolic-functions',]def __init__(self, ctx):self.ctx = ctx# Allows injecting additional linker paths used by any recipe.# This can also be modified by recipes (like the librt recipe)# to make sure that some sort of global resource is available &# linked for all others.self.extra_global_link_paths = []def __str__(self):return self.arch@propertydef ndk_lib_dir(self):return join(self.ctx.ndk.sysroot_lib_dir, self.command_prefix)@propertydef ndk_lib_dir_versioned(self):return join(self.ndk_lib_dir, str(self.ctx.ndk_api))@propertydef include_dirs(self):return ["{}/{}".format(self.ctx.include_dir,d.format(arch=self))for d in self.ctx.include_dirs]@propertydef target(self):# As of NDK r19, the toolchains installed by default with the# NDK may be used in-place. The make_standalone_toolchain.py script# is no longer needed for interfacing with arbitrary build systems.# See: https://developer.android.com/ndk/guides/other_build_systemsreturn '{triplet}{ndk_api}'.format(triplet=self.command_prefix, ndk_api=self.ctx.ndk_api)@propertydef clang_exe(self):"""Full path of the clang compiler depending on the android's ndkversion used."""return self.get_clang_exe()@propertydef clang_exe_cxx(self):"""Full path of the clang++ compiler depending on the android's ndkversion used."""return self.get_clang_exe(plus_plus=True)def get_clang_exe(self, with_target=False, plus_plus=False):"""Returns the full path of the clang/clang++ compiler, supports twokwargs:- `with_target`: prepend `target` to clang- `plus_plus`: will return the clang++ compiler (defaults to `False`)"""compiler = 'clang'if with_target:compiler = '{target}-{compiler}'.format(target=self.target, compiler=compiler)if plus_plus:compiler += '++'return join(self.ctx.ndk.llvm_bin_dir, compiler)def get_env(self, with_flags_in_cc=True):env = {}# HOME: User's home directory## Many tools including p4a store outputs in the user's home# directory. This is found from the HOME environment variable# and falls back to the system account database. Setting HOME# can be used to globally divert these tools to use a different# path. Furthermore, in containerized environments the user may# not exist in the account database, so if HOME isn't set than# these tools will fail.if 'HOME' in environ:env['HOME'] = environ['HOME']# CFLAGS/CXXFLAGS: the processor flagsenv['CFLAGS'] = ' '.join(self.common_cflags).format(target=self.target)if self.arch_cflags:# each architecture may have has his own CFLAGSenv['CFLAGS'] += ' ' + ' '.join(self.arch_cflags)env['CXXFLAGS'] = env['CFLAGS']# CPPFLAGS (for macros and includes)env['CPPFLAGS'] = ' '.join(self.common_cppflags).format(ctx=self.ctx,command_prefix=self.command_prefix,python_includes=join(self.ctx.get_python_install_dir(self.arch),'include/python{}'.format(self.ctx.python_recipe.version[0:3]),),)# LDFLAGS: Link the extra global link paths first before anything else# (such that overriding system libraries with them is possible)env['LDFLAGS'] = (' '+ " ".join(["-L'"+ link_path.replace("'", "'\"'\"'")+ "'" # no shlex.quote in py2for link_path in self.extra_global_link_paths])+ ' ' + ' '.join(self.common_ldflags).format(ctx_libs_dir=self.ctx.get_libs_dir(self.arch)))# LDLIBS: Library flags or names given to compilers when they are# supposed to invoke the linker.env['LDLIBS'] = ' '.join(self.common_ldlibs)# CCACHEccache = ''if self.ctx.ccache and bool(int(environ.get('USE_CCACHE', '1'))):# print('ccache found, will optimize builds')ccache = self.ctx.ccache + ' 'env['USE_CCACHE'] = '1'env['NDK_CCACHE'] = self.ctx.ccacheenv.update({k: v for k, v in environ.items() if k.startswith('CCACHE_')})# Compiler: `CC` and `CXX` (and make sure that the compiler exists)env['PATH'] = self.ctx.env['PATH']cc = shutil.which(self.clang_exe, path=env['PATH'])if cc is None:print('Searching path are: {!r}'.format(env['PATH']))raise BuildInterruptingException('Couldn\'t find executable for CC. This indicates a ''problem locating the {} executable in the Android ''NDK, not that you don\'t have a normal compiler ''installed. Exiting.'.format(self.clang_exe))if with_flags_in_cc:env['CC'] = '{ccache}{exe} {cflags}'.format(exe=self.clang_exe,ccache=ccache,cflags=env['CFLAGS'])env['CXX'] = '{ccache}{execxx} {cxxflags}'.format(execxx=self.clang_exe_cxx,ccache=ccache,cxxflags=env['CXXFLAGS'])else:env['CC'] = '{ccache}{exe}'.format(exe=self.clang_exe,ccache=ccache)env['CXX'] = '{ccache}{execxx}'.format(execxx=self.clang_exe_cxx,ccache=ccache)# Android's LLVM binutilsenv['AR'] = self.ctx.ndk.llvm_arenv['RANLIB'] = self.ctx.ndk.llvm_ranlibenv['STRIP'] = f'{self.ctx.ndk.llvm_strip} --strip-unneeded'env['READELF'] = self.ctx.ndk.llvm_readelfenv['OBJCOPY'] = self.ctx.ndk.llvm_objcopyenv['MAKE'] = 'make -j{}'.format(str(cpu_count()))# Android's arch/toolchainenv['ARCH'] = self.archenv['NDK_API'] = 'android-{}'.format(str(self.ctx.ndk_api))# Custom linker optionsenv['LDSHARED'] = env['CC'] + ' ' + ' '.join(self.common_ldshared)# Host python (used by some recipes)hostpython_recipe = Recipe.get_recipe('host' + self.ctx.python_recipe.name, self.ctx)env['BUILDLIB_PATH'] = join(hostpython_recipe.get_build_dir(self.arch),'native-build','build','lib.{}-{}'.format(build_platform,self.ctx.python_recipe.major_minor_version_string,),)# for reproducible buildsif 'SOURCE_DATE_EPOCH' in environ:for k in 'LC_ALL TZ SOURCE_DATE_EPOCH PYTHONHASHSEED BUILD_DATE BUILD_TIME'.split():if k in environ:env[k] = environ[k]return envclass ArchARM(Arch):arch = "armeabi"command_prefix = 'arm-linux-androideabi'@propertydef target(self):target_data = self.command_prefix.split('-')return '{triplet}{ndk_api}'.format(triplet='-'.join(['armv7a', target_data[1], target_data[2]]),ndk_api=self.ctx.ndk_api,)class ArchARMv7_a(ArchARM):arch = 'armeabi-v7a'arch_cflags = ['-march=armv7-a','-mfloat-abi=softfp','-mfpu=vfp','-mthumb','-fPIC',]class Archx86(Arch):arch = 'x86'command_prefix = 'i686-linux-android'arch_cflags = ['-march=i686','-mssse3','-mfpmath=sse','-m32','-fPIC',]class Archx86_64(Arch):arch = 'x86_64'command_prefix = 'x86_64-linux-android'arch_cflags = ['-march=x86-64','-msse4.2','-mpopcnt','-m64','-fPIC',]class ArchAarch_64(Arch):arch = 'arm64-v8a'command_prefix = 'aarch64-linux-android'arch_cflags = ['-march=armv8-a','-fPIC'# '-I' + join(dirname(__file__), 'includes', 'arm64-v8a'),]# Note: This `EXTRA_CFLAGS` below should target the commented `include`# above in `arch_cflags`. The original lines were added during the Sdl2's# bootstrap creation, and modified/commented during the migration to the# NDK r19 build system, because it seems that we don't need it anymore,# do we need them?# def get_env(self, with_flags_in_cc=True):# env = super().get_env(with_flags_in_cc)# env['EXTRA_CFLAGS'] = self.arch_cflags[-1]# return env
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。