Skip to content

Commit bbad205

Browse files
author
Mark W. Alexander
committed
This recipe uses libtool which doesn't handle --sysroot well and is completely
clueless about -isysroot and -isystem so it can't link. It traps the sh.make failure and then manually links and installs libffi.so
1 parent b591cbb commit bbad205

File tree

1 file changed

+74
-62
lines changed

1 file changed

+74
-62
lines changed
Lines changed: 74 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,83 @@
1+
from os.path import exists, join
12
from pythonforandroid.recipe import Recipe
2-
from pythonforandroid.logger import shprint
3+
from pythonforandroid.logger import info, shprint
34
from pythonforandroid.util import current_directory
4-
from os.path import exists, join
55
import sh
6-
import glob
76

87

98
class LibffiRecipe(Recipe):
10-
name = 'libffi'
11-
version = 'v3.2.1'
12-
url = 'https://github.com/atgreen/libffi/archive/{version}.zip'
13-
14-
patches = ['remove-version-info.patch']
15-
16-
def get_host(self, arch):
17-
with current_directory(self.get_build_dir(arch.arch)):
18-
host = None
19-
with open('Makefile') as f:
20-
for line in f:
21-
if line.startswith('host = '):
22-
host = line.strip()[7:]
23-
break
24-
25-
if not host or not exists(host):
26-
raise RuntimeError('failed to find build output! ({})'
27-
.format(host))
28-
29-
return host
30-
31-
def should_build(self, arch):
32-
# return not bool(glob.glob(join(self.ctx.get_libs_dir(arch.arch),
33-
# 'libffi.so*')))
34-
return not exists(join(self.ctx.get_libs_dir(arch.arch), 'libffi.so'))
35-
# return not exists(join(self.ctx.get_python_install_dir(), 'lib',
36-
# 'libffi.so'))
37-
38-
def build_arch(self, arch):
39-
env = self.get_recipe_env(arch)
40-
with current_directory(self.get_build_dir(arch.arch)):
41-
if not exists('configure'):
42-
shprint(sh.Command('./autogen.sh'), _env=env)
43-
shprint(sh.Command('autoreconf'), '-vif', _env=env)
44-
shprint(sh.Command('./configure'), '--host=' + arch.toolchain_prefix,
45-
'--prefix=' + self.ctx.get_python_install_dir(),
46-
'--enable-shared', _env=env)
47-
shprint(sh.make, '-j5', 'libffi.la', _env=env)
48-
49-
50-
# dlname = None
51-
# with open(join(host, 'libffi.la')) as f:
52-
# for line in f:
53-
# if line.startswith('dlname='):
54-
# dlname = line.strip()[8:-1]
55-
# break
56-
#
57-
# if not dlname or not exists(join(host, '.libs', dlname)):
58-
# raise RuntimeError('failed to locate shared object! ({})'
59-
# .format(dlname))
60-
61-
# shprint(sh.sed, '-i', 's/^dlname=.*$/dlname=\'libffi.so\'/', join(host, 'libffi.la'))
62-
63-
shprint(sh.cp, '-t', self.ctx.get_libs_dir(arch.arch),
64-
join(self.get_host(arch), '.libs', 'libffi.so')) #,
65-
# join(host, 'libffi.la'))
66-
67-
def get_include_dirs(self, arch):
68-
return [join(self.get_build_dir(arch.arch), self.get_host(arch), 'include')]
9+
name = 'libffi'
10+
version = 'v3.2.1'
11+
url = 'https://github.com/atgreen/libffi/archive/{version}.zip'
12+
13+
patches = ['remove-version-info.patch']
14+
15+
def get_host(self, arch):
16+
with current_directory(self.get_build_dir(arch.arch)):
17+
host = None
18+
with open('Makefile') as f:
19+
for line in f:
20+
if line.startswith('host = '):
21+
host = line.strip()[7:]
22+
break
23+
24+
if not host or not exists(host):
25+
raise RuntimeError('failed to find build output! ({})'
26+
.format(host))
27+
28+
return host
29+
30+
def should_build(self, arch):
31+
return not exists(join(self.ctx.get_libs_dir(arch.arch), 'libffi.so'))
32+
33+
def build_arch(self, arch):
34+
env = self.get_recipe_env(arch)
35+
with current_directory(self.get_build_dir(arch.arch)):
36+
if not exists('configure'):
37+
shprint(sh.Command('./autogen.sh'), _env=env)
38+
shprint(sh.Command('autoreconf'), '-vif', _env=env)
39+
shprint(sh.Command('./configure'),
40+
'--host=' + arch.toolchain_prefix,
41+
'--prefix=' + self.ctx.get_python_install_dir(),
42+
'--enable-shared', _env=env)
43+
#'--with-sysroot={}'.format(self.ctx.ndk_platform),
44+
#'--target={}'.format(arch.toolchain_prefix),
45+
46+
# ndk 15 introduces unified headers required --sysroot and
47+
# -isysroot for libraries and headers. libtool's head explodes
48+
# trying to weave them into it's own magic. The result is a link
49+
# failure tryng to link libc. We call make to compile the bits
50+
# and manually link...
51+
52+
try:
53+
shprint(sh.make, '-j5', 'libffi.la', _env=env)
54+
except sh.ErrorReturnCode_2:
55+
info("make libffi.la failed as expected")
56+
cc = sh.Command(env['CC'].split()[0])
57+
cflags = env['CC'].split()[1:]
58+
59+
cflags.extend(['-march=armv7-a', '-mfloat-abi=softfp', '-mfpu=vfp',
60+
'-mthumb', '-shared', '-fPIC', '-DPIC',
61+
'src/.libs/prep_cif.o', 'src/.libs/types.o',
62+
'src/.libs/raw_api.o', 'src/.libs/java_raw_api.o',
63+
'src/.libs/closures.o', 'src/arm/.libs/sysv.o',
64+
'src/arm/.libs/ffi.o', ]
65+
)
66+
67+
ldflags = env['LDFLAGS'].split()
68+
cflags.extend(ldflags)
69+
cflags.extend(['-Wl,-soname', '-Wl,libffi.so', '-o',
70+
'.libs/libffi.so'])
71+
72+
with current_directory(self.get_host(arch)):
73+
shprint(cc, *cflags, _env=env)
74+
75+
shprint(sh.cp, '-t', self.ctx.get_libs_dir(arch.arch),
76+
join(self.get_host(arch), '.libs', 'libffi.so'))
77+
78+
def get_include_dirs(self, arch):
79+
return [join(self.get_build_dir(arch.arch), self.get_host(arch),
80+
'include')]
6981

7082

7183
recipe = LibffiRecipe()

0 commit comments

Comments
 (0)