diff --git a/pythonforandroid/archs.py b/pythonforandroid/archs.py index 656bf95850..194b72db8a 100644 --- a/pythonforandroid/archs.py +++ b/pythonforandroid/archs.py @@ -30,13 +30,24 @@ def include_dirs(self): d.format(arch=self)) for d in self.ctx.include_dirs] - def get_env(self, with_flags_in_cc=True): + def get_env(self, with_flags_in_cc=True, clang=False): env = {} - env['CFLAGS'] = ' '.join([ - '-DANDROID', '-mandroid', '-fomit-frame-pointer' - ' -D__ANDROID_API__={}'.format(self.ctx.ndk_api), - ]) + cflags = [ + '-DANDROID', + '-fomit-frame-pointer', + '-D__ANDROID_API__={}'.format(self.ctx.ndk_api)] + if not clang: + cflags += ['-mandroid'] + else: + cflags += ['-target armv7-none-linux-androideabi'] + android_host = 'arm-linux-androideabi' + platform_dir = join(self.ctx.ndk_dir, 'platforms', 'android-{}'.format(self.ctx.ndk_api), 'arch-arm') + toolchain = '{android_host}-4.9'.format(android_host=android_host) + toolchain = join(self.ctx.ndk_dir, 'toolchains', toolchain, 'prebuilt', 'linux-x86_64') + cflags += ['-gcc-toolchain {}'.format(toolchain)] + + env['CFLAGS'] = ' '.join(cflags) env['LDFLAGS'] = ' ' sysroot = join(self.ctx._ndk_dir, 'sysroot') @@ -82,8 +93,19 @@ def get_env(self, with_flags_in_cc=True): env['NDK_CCACHE'] = self.ctx.ccache env.update({k: v for k, v in environ.items() if k.startswith('CCACHE_')}) - cc = find_executable('{command_prefix}-gcc'.format( - command_prefix=command_prefix), path=environ['PATH']) + if clang: + clang_path = join( + self.ctx.ndk_dir, 'toolchains', 'llvm', 'prebuilt', + 'linux-x86_64', 'bin') + environ['PATH'] = '{clang_path}:{path}'.format( + clang_path=clang_path, path=environ['PATH']) + exe = join(clang_path, 'clang') + execxx = join(clang_path, 'clang++') + else: + exe = '{command_prefix}-gcc'.format(command_prefix=command_prefix) + execxx = '{command_prefix}-g++'.format(command_prefix=command_prefix) + + cc = find_executable(exe, path=environ['PATH']) if cc is None: print('Searching path are: {!r}'.format(environ['PATH'])) warning('Couldn\'t find executable for CC. This indicates a ' @@ -93,20 +115,20 @@ def get_env(self, with_flags_in_cc=True): exit(1) if with_flags_in_cc: - env['CC'] = '{ccache}{command_prefix}-gcc {cflags}'.format( - command_prefix=command_prefix, + env['CC'] = '{ccache}{exe} {cflags}'.format( + exe=exe, ccache=ccache, cflags=env['CFLAGS']) - env['CXX'] = '{ccache}{command_prefix}-g++ {cxxflags}'.format( - command_prefix=command_prefix, + env['CXX'] = '{ccache}{execxx} {cxxflags}'.format( + execxx=execxx, ccache=ccache, cxxflags=env['CXXFLAGS']) else: - env['CC'] = '{ccache}{command_prefix}-gcc'.format( - command_prefix=command_prefix, + env['CC'] = '{ccache}{exe}'.format( + exe=exe, ccache=ccache) - env['CXX'] = '{ccache}{command_prefix}-g++'.format( - command_prefix=command_prefix, + env['CXX'] = '{ccache}{execxx}'.format( + execxx=execxx, ccache=ccache) env['AR'] = '{}-ar'.format(command_prefix) @@ -151,8 +173,8 @@ class ArchARM(Arch): class ArchARMv7_a(ArchARM): arch = 'armeabi-v7a' - def get_env(self, with_flags_in_cc=True): - env = super(ArchARMv7_a, self).get_env(with_flags_in_cc) + def get_env(self, with_flags_in_cc=True, clang=False): + env = super(ArchARMv7_a, self).get_env(with_flags_in_cc, clang=clang) env['CFLAGS'] = (env['CFLAGS'] + (' -march=armv7-a -mfloat-abi=softfp ' '-mfpu=vfp -mthumb')) @@ -166,8 +188,8 @@ class Archx86(Arch): command_prefix = 'i686-linux-android' platform_dir = 'arch-x86' - def get_env(self, with_flags_in_cc=True): - env = super(Archx86, self).get_env(with_flags_in_cc) + def get_env(self, with_flags_in_cc=True, clang=False): + env = super(Archx86, self).get_env(with_flags_in_cc, clang=clang) env['CFLAGS'] = (env['CFLAGS'] + ' -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32') env['CXXFLAGS'] = env['CFLAGS'] @@ -180,8 +202,8 @@ class Archx86_64(Arch): command_prefix = 'x86_64-linux-android' platform_dir = 'arch-x86_64' - def get_env(self, with_flags_in_cc=True): - env = super(Archx86_64, self).get_env(with_flags_in_cc) + def get_env(self, with_flags_in_cc=True, clang=False): + env = super(Archx86_64, self).get_env(with_flags_in_cc, clang=clang) env['CFLAGS'] = (env['CFLAGS'] + ' -march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel') env['CXXFLAGS'] = env['CFLAGS'] @@ -194,8 +216,8 @@ class ArchAarch_64(Arch): command_prefix = 'aarch64-linux-android' platform_dir = 'arch-arm64' - def get_env(self, with_flags_in_cc=True): - env = super(ArchAarch_64, self).get_env(with_flags_in_cc) + def get_env(self, with_flags_in_cc=True, clang=False): + env = super(ArchAarch_64, self).get_env(with_flags_in_cc, clang=clang) incpath = ' -I' + join(dirname(__file__), 'includes', 'arm64-v8a') env['EXTRA_CFLAGS'] = incpath env['CFLAGS'] += incpath diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index 2d8691d62f..20b50ef731 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -406,12 +406,12 @@ def unpack(self, arch): else: info('{} is already unpacked, skipping'.format(self.name)) - def get_recipe_env(self, arch=None, with_flags_in_cc=True): + def get_recipe_env(self, arch=None, with_flags_in_cc=True, clang=False): """Return the env specialized for the recipe """ if arch is None: arch = self.filtered_archs[0] - return arch.get_env(with_flags_in_cc=with_flags_in_cc) + return arch.get_env(with_flags_in_cc=with_flags_in_cc, clang=clang) def prebuild_arch(self, arch): '''Run any pre-build tasks for the Recipe. By default, this checks if