Skip to content

Commit 5e503e6

Browse files
committed
Migrates gevent to new python3 recipe
Also adds unit tests for checking flags are being cleaned up properly.
1 parent 645002c commit 5e503e6

File tree

4 files changed

+135
-36
lines changed

4 files changed

+135
-36
lines changed

pythonforandroid/recipes/gevent/__init__.py

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,48 @@
1+
import re
12
import os
2-
from pythonforandroid.recipe import CompiledComponentsPythonRecipe
3+
import sh
4+
from pythonforandroid.logger import info, shprint
5+
from pythonforandroid.recipe import CythonRecipe
36

47

5-
class GeventRecipe(CompiledComponentsPythonRecipe):
6-
version = '1.1.1'
8+
class GeventRecipe(CythonRecipe):
9+
version = '1.3.7'
710
url = 'https://pypi.python.org/packages/source/g/gevent/gevent-{version}.tar.gz'
8-
depends = [('python2', 'python3crystax'), 'greenlet']
9-
patches = ["gevent.patch"]
11+
depends = ['greenlet']
12+
patches = ["cross_compiling.patch"]
13+
14+
def build_cython_components(self, arch):
15+
"""
16+
Hack to make it link properly to librt, inserted automatically by the
17+
installer (Note: the librt doesn't exist in android but it is
18+
integrated into libc, so we create a symbolic link which we will
19+
remove when our build finishes)
20+
"""
21+
link_c = os.path.join(self.ctx.ndk_platform, 'usr', 'lib', 'libc')
22+
link_rt = os.path.join(self.ctx.ndk_platform, 'usr', 'lib', 'librt')
23+
shprint(sh.ln, '-sf', link_c + '.so', link_rt + '.so')
24+
shprint(sh.ln, '-sf', link_c + '.a', link_rt + '.a')
25+
super(GeventRecipe, self).build_cython_components(arch)
26+
shprint(sh.rm, link_rt + '.so')
27+
shprint(sh.rm, link_rt + '.a')
1028

1129
def get_recipe_env(self, arch=None, with_flags_in_cc=True):
30+
"""
31+
- Moves all -I<inc> -D<macro> from CFLAGS to CPPFLAGS environment.
32+
- Moves all -l<lib> from LDFLAGS to LIBS environment.
33+
- Fixes linker name (use cross compiler) and flags (appends LIBS)
34+
"""
1235
env = super(GeventRecipe, self).get_recipe_env(arch, with_flags_in_cc)
13-
# sets linker to use the correct gcc (cross compiler)
14-
env['LDSHARED'] = env['CC'] + ' -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions'
1536
# CFLAGS may only be used to specify C compiler flags, for macro definitions use CPPFLAGS
16-
env['CPPFLAGS'] = env['CFLAGS'] + ' -I{}/sources/python/3.5/include/python/'.format(self.ctx.ndk_dir)
17-
env['CFLAGS'] = ''
37+
regex = re.compile(r'(?:\s|^)-[DI][\S]+')
38+
env['CPPFLAGS'] = ''.join(re.findall(regex, env['CFLAGS'])).strip()
39+
env['CFLAGS'] = re.sub(regex, '', env['CFLAGS'])
40+
info('Moved "{}" from CFLAGS to CPPFLAGS.'.format(env['CPPFLAGS']))
1841
# LDFLAGS may only be used to specify linker flags, for libraries use LIBS
19-
env['LDFLAGS'] = env['LDFLAGS'].replace('-lm', '').replace('-lcrystax', '')
20-
env['LDFLAGS'] += ' -L{}'.format(os.path.join(self.ctx.bootstrap.build_dir, 'libs', arch.arch))
21-
env['LIBS'] = ' -lm'
22-
if self.ctx.ndk == 'crystax':
23-
env['LIBS'] += ' -lcrystax -lpython{}m'.format(self.ctx.python_recipe.version[0:3])
24-
env['LDSHARED'] += env['LIBS']
42+
regex = re.compile(r'(?:\s|^)-l[\w\.]+')
43+
env['LIBS'] = ''.join(re.findall(regex, env['LDFLAGS'])).strip()
44+
env['LDFLAGS'] = re.sub(regex, '', env['LDFLAGS'])
45+
info('Moved "{}" from LDFLAGS to LIBS.'.format(env['LIBS']))
2546
return env
2647

2748

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
diff --git a/_setupares.py b/_setupares.py
2+
index dd184de6..bb16bebe 100644
3+
--- a/_setupares.py
4+
+++ b/_setupares.py
5+
@@ -43,7 +43,7 @@ else:
6+
ares_configure_command = ' '.join([
7+
"(cd ", quoted_dep_abspath('c-ares'),
8+
" && if [ -r ares_build.h ]; then cp ares_build.h ares_build.h.orig; fi ",
9+
- " && sh ./configure --disable-dependency-tracking " + _m32 + "CONFIG_COMMANDS= ",
10+
+ " && sh ./configure --host={} --disable-dependency-tracking ".format(os.environ['TOOLCHAIN_PREFIX']) + _m32 + "CONFIG_COMMANDS= ",
11+
" && cp ares_config.h ares_build.h \"$OLDPWD\" ",
12+
" && cat ares_build.h ",
13+
" && if [ -r ares_build.h.orig ]; then mv ares_build.h.orig ares_build.h; fi)",
14+
diff --git a/_setuplibev.py b/_setuplibev.py
15+
index 2a5841bf..b6433c94 100644
16+
--- a/_setuplibev.py
17+
+++ b/_setuplibev.py
18+
@@ -31,7 +31,7 @@ LIBEV_EMBED = should_embed('libev')
19+
# and the PyPy branch will clean it up.
20+
libev_configure_command = ' '.join([
21+
"(cd ", quoted_dep_abspath('libev'),
22+
- " && sh ./configure ",
23+
+ " && sh ./configure --host={} ".format(os.environ['TOOLCHAIN_PREFIX']),
24+
" && cp config.h \"$OLDPWD\"",
25+
")",
26+
'> configure-output.txt'

pythonforandroid/recipes/gevent/gevent.patch

Lines changed: 0 additions & 21 deletions
This file was deleted.

tests/recipes/test_gevent.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import unittest
2+
from mock import patch
3+
from pythonforandroid.archs import ArchARMv7_a
4+
from pythonforandroid.build import Context
5+
from pythonforandroid.recipe import Recipe
6+
7+
8+
class TestGeventRecipe(unittest.TestCase):
9+
10+
def setUp(self):
11+
"""
12+
Setups recipe and context.
13+
"""
14+
self.context = Context()
15+
self.context.ndk_api = 21
16+
self.context.android_api = 27
17+
self.arch = ArchARMv7_a(self.context)
18+
self.recipe = Recipe.get_recipe('gevent', self.context)
19+
20+
def test_get_recipe_env(self):
21+
"""
22+
Makes sure `get_recipe_env()` sets compilation flags properly.
23+
"""
24+
mocked_cflags = (
25+
'-DANDROID -fomit-frame-pointer -D__ANDROID_API__=27 -mandroid '
26+
'-isystem /path/to/isystem '
27+
'-I/path/to/include1 '
28+
'-isysroot /path/to/sysroot '
29+
'-I/path/to/include2 '
30+
'-march=armv7-a -mfloat-abi=softfp -mfpu=vfp -mthumb '
31+
'-I/path/to/python3-libffi-openssl/include'
32+
)
33+
mocked_ldflags = (
34+
' --sysroot /path/to/sysroot '
35+
'-lm '
36+
'-L/path/to/library1 '
37+
'-L/path/to/library2 '
38+
'-lpython3.7m '
39+
# checks the regex doesn't parse `python3-libffi-openssl` as a `-libffi`
40+
'-L/path/to/python3-libffi-openssl/library3 '
41+
)
42+
mocked_env = {
43+
'CFLAGS': mocked_cflags,
44+
'LDFLAGS': mocked_ldflags,
45+
}
46+
with patch('pythonforandroid.recipe.CythonRecipe.get_recipe_env') as m_get_recipe_env:
47+
m_get_recipe_env.return_value = mocked_env
48+
env = self.recipe.get_recipe_env()
49+
expected_cflags = (
50+
' -fomit-frame-pointer -mandroid -isystem /path/to/isystem'
51+
' -isysroot /path/to/sysroot'
52+
' -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -mthumb'
53+
)
54+
expected_cppflags = (
55+
'-DANDROID -D__ANDROID_API__=27 '
56+
'-I/path/to/include1 '
57+
'-I/path/to/include2 '
58+
'-I/path/to/python3-libffi-openssl/include'
59+
)
60+
expected_ldflags = (
61+
' --sysroot /path/to/sysroot'
62+
' -L/path/to/library1'
63+
' -L/path/to/library2'
64+
' -L/path/to/python3-libffi-openssl/library3 '
65+
)
66+
expected_libs = '-lm -lpython3.7m'
67+
expected_env = {
68+
'CFLAGS': expected_cflags,
69+
'CPPFLAGS': expected_cppflags,
70+
'LDFLAGS': expected_ldflags,
71+
'LIBS': expected_libs,
72+
}
73+
self.assertEqual(expected_env, env)

0 commit comments

Comments
 (0)