Skip to content

Commit e07416a

Browse files
titoopacam
authored andcommitted
Add ability to compile recipes with clang
The android ndk has been migrated his default compiler from gcc to clang and soon will be removed from the ndk. Here we prepare p4a to compile recipes with clang, which will allow us to successfully compile an updated openssl libs. Without this openssl upgrade we will not be able to grant support to python3's _ssl.so module. Note: The default p4a compiler still is gcc...so...no changes on the compile behaviour unless explicitly requested References: #1478
1 parent e7aa16b commit e07416a

File tree

2 files changed

+47
-25
lines changed

2 files changed

+47
-25
lines changed

pythonforandroid/archs.py

Lines changed: 45 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,24 @@ def include_dirs(self):
3030
d.format(arch=self))
3131
for d in self.ctx.include_dirs]
3232

33-
def get_env(self, with_flags_in_cc=True):
33+
def get_env(self, with_flags_in_cc=True, clang=False):
3434
env = {}
3535

36-
env['CFLAGS'] = ' '.join([
37-
'-DANDROID', '-mandroid', '-fomit-frame-pointer'
38-
' -D__ANDROID_API__={}'.format(self.ctx.ndk_api),
39-
])
36+
cflags = [
37+
'-DANDROID',
38+
'-fomit-frame-pointer',
39+
'-D__ANDROID_API__={}'.format(self.ctx.ndk_api)]
40+
if not clang:
41+
cflags += ['-mandroid']
42+
else:
43+
cflags += ['-target armv7-none-linux-androideabi']
44+
android_host = 'arm-linux-androideabi'
45+
platform_dir = join(self.ctx.ndk_dir, 'platforms', 'android-{}'.format(self.ctx.ndk_api), 'arch-arm')
46+
toolchain = '{android_host}-4.9'.format(android_host=android_host)
47+
toolchain = join(self.ctx.ndk_dir, 'toolchains', toolchain, 'prebuilt', 'linux-x86_64')
48+
cflags += ['-gcc-toolchain {}'.format(toolchain)]
49+
50+
env['CFLAGS'] = ' '.join(cflags)
4051
env['LDFLAGS'] = ' '
4152

4253
sysroot = join(self.ctx._ndk_dir, 'sysroot')
@@ -82,8 +93,19 @@ def get_env(self, with_flags_in_cc=True):
8293
env['NDK_CCACHE'] = self.ctx.ccache
8394
env.update({k: v for k, v in environ.items() if k.startswith('CCACHE_')})
8495

85-
cc = find_executable('{command_prefix}-gcc'.format(
86-
command_prefix=command_prefix), path=environ['PATH'])
96+
if clang:
97+
clang_path = join(
98+
self.ctx.ndk_dir, 'toolchains', 'llvm', 'prebuilt',
99+
'linux-x86_64', 'bin')
100+
environ['PATH'] = '{clang_path}:{path}'.format(
101+
clang_path=clang_path, path=environ['PATH'])
102+
exe = join(clang_path, 'clang')
103+
execxx = join(clang_path, 'clang++')
104+
else:
105+
exe = '{command_prefix}-gcc'.format(command_prefix=command_prefix)
106+
execxx = '{command_prefix}-g++'.format(command_prefix=command_prefix)
107+
108+
cc = find_executable(exe, path=environ['PATH'])
87109
if cc is None:
88110
print('Searching path are: {!r}'.format(environ['PATH']))
89111
warning('Couldn\'t find executable for CC. This indicates a '
@@ -93,20 +115,20 @@ def get_env(self, with_flags_in_cc=True):
93115
exit(1)
94116

95117
if with_flags_in_cc:
96-
env['CC'] = '{ccache}{command_prefix}-gcc {cflags}'.format(
97-
command_prefix=command_prefix,
118+
env['CC'] = '{ccache}{exe} {cflags}'.format(
119+
exe=exe,
98120
ccache=ccache,
99121
cflags=env['CFLAGS'])
100-
env['CXX'] = '{ccache}{command_prefix}-g++ {cxxflags}'.format(
101-
command_prefix=command_prefix,
122+
env['CXX'] = '{ccache}{execxx} {cxxflags}'.format(
123+
execxx=execxx,
102124
ccache=ccache,
103125
cxxflags=env['CXXFLAGS'])
104126
else:
105-
env['CC'] = '{ccache}{command_prefix}-gcc'.format(
106-
command_prefix=command_prefix,
127+
env['CC'] = '{ccache}{exe}'.format(
128+
exe=exe,
107129
ccache=ccache)
108-
env['CXX'] = '{ccache}{command_prefix}-g++'.format(
109-
command_prefix=command_prefix,
130+
env['CXX'] = '{ccache}{execxx}'.format(
131+
execxx=execxx,
110132
ccache=ccache)
111133

112134
env['AR'] = '{}-ar'.format(command_prefix)
@@ -151,8 +173,8 @@ class ArchARM(Arch):
151173
class ArchARMv7_a(ArchARM):
152174
arch = 'armeabi-v7a'
153175

154-
def get_env(self, with_flags_in_cc=True):
155-
env = super(ArchARMv7_a, self).get_env(with_flags_in_cc)
176+
def get_env(self, with_flags_in_cc=True, clang=False):
177+
env = super(ArchARMv7_a, self).get_env(with_flags_in_cc, clang=clang)
156178
env['CFLAGS'] = (env['CFLAGS'] +
157179
(' -march=armv7-a -mfloat-abi=softfp '
158180
'-mfpu=vfp -mthumb'))
@@ -166,8 +188,8 @@ class Archx86(Arch):
166188
command_prefix = 'i686-linux-android'
167189
platform_dir = 'arch-x86'
168190

169-
def get_env(self, with_flags_in_cc=True):
170-
env = super(Archx86, self).get_env(with_flags_in_cc)
191+
def get_env(self, with_flags_in_cc=True, clang=False):
192+
env = super(Archx86, self).get_env(with_flags_in_cc, clang=clang)
171193
env['CFLAGS'] = (env['CFLAGS'] +
172194
' -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32')
173195
env['CXXFLAGS'] = env['CFLAGS']
@@ -180,8 +202,8 @@ class Archx86_64(Arch):
180202
command_prefix = 'x86_64-linux-android'
181203
platform_dir = 'arch-x86'
182204

183-
def get_env(self, with_flags_in_cc=True):
184-
env = super(Archx86_64, self).get_env(with_flags_in_cc)
205+
def get_env(self, with_flags_in_cc=True, clang=False):
206+
env = super(Archx86_64, self).get_env(with_flags_in_cc, clang=clang)
185207
env['CFLAGS'] = (env['CFLAGS'] +
186208
' -march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel')
187209
env['CXXFLAGS'] = env['CFLAGS']
@@ -194,8 +216,8 @@ class ArchAarch_64(Arch):
194216
command_prefix = 'aarch64-linux-android'
195217
platform_dir = 'arch-arm64'
196218

197-
def get_env(self, with_flags_in_cc=True):
198-
env = super(ArchAarch_64, self).get_env(with_flags_in_cc)
219+
def get_env(self, with_flags_in_cc=True, clang=False):
220+
env = super(ArchAarch_64, self).get_env(with_flags_in_cc, clang=clang)
199221
incpath = ' -I' + join(dirname(__file__), 'includes', 'arm64-v8a')
200222
env['EXTRA_CFLAGS'] = incpath
201223
env['CFLAGS'] += incpath

pythonforandroid/recipe.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,12 +406,12 @@ def unpack(self, arch):
406406
else:
407407
info('{} is already unpacked, skipping'.format(self.name))
408408

409-
def get_recipe_env(self, arch=None, with_flags_in_cc=True):
409+
def get_recipe_env(self, arch=None, with_flags_in_cc=True, clang=False):
410410
"""Return the env specialized for the recipe
411411
"""
412412
if arch is None:
413413
arch = self.filtered_archs[0]
414-
return arch.get_env(with_flags_in_cc=with_flags_in_cc)
414+
return arch.get_env(with_flags_in_cc=with_flags_in_cc, clang=clang)
415415

416416
def prebuild_arch(self, arch):
417417
'''Run any pre-build tasks for the Recipe. By default, this checks if

0 commit comments

Comments
 (0)