Skip to content

Extend numpy recipe to support python3 #1343

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 28 additions & 28 deletions pythonforandroid/recipes/numpy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,48 @@
from pythonforandroid.recipe import CompiledComponentsPythonRecipe
from pythonforandroid.toolchain import warning
from os.path import join


class NumpyRecipe(CompiledComponentsPythonRecipe):

version = '1.9.2'
url = 'https://pypi.python.org/packages/source/n/numpy/numpy-{version}.tar.gz'
site_packages_name= 'numpy'
version = '1.15.1'
url = 'https://pypi.python.org/packages/source/n/numpy/numpy-{version}.zip'
site_packages_name = 'numpy'

depends = ['python2']
depends = [('python2', 'python3crystax')]

patches = ['patches/fix-numpy.patch',
'patches/prevent_libs_check.patch',
'patches/ar.patch',
'patches/lib.patch']
patches = [
join('patches', 'fix-numpy.patch'),
join('patches', 'prevent_libs_check.patch'),
join('patches', 'ar.patch'),
join('patches', 'lib.patch'),
join('patches', 'python2-fixes.patch')
]

def get_recipe_env(self, arch):
""" looks like numpy has no proper -L flags. Code copied and adapted from
https://github.com/frmdstryr/p4a-numpy/
"""

env = super(NumpyRecipe, self).get_recipe_env(arch)
#: Hack add path L to crystax as a CFLAG

py_ver = '3.5'
if {'python2crystax', 'python2'} & set(self.ctx.recipe_build_order):
py_ver = '2.7'

py_so = '2.7' if py_ver == '2.7' else '3.5m'
flags = " -L{} --sysroot={}".format(
join(self.ctx.ndk_platform, 'usr', 'lib'),
self.ctx.ndk_platform
)

if self.ctx.ndk == 'crystax':
py_ver = self.ctx.python_recipe.version[0:3]
src_dir = join(self.ctx.ndk_dir, 'sources')
py_inc_dir = join(src_dir, 'python', py_ver, 'include', 'python')
py_lib_dir = join(src_dir, 'python', py_ver, 'libs', arch.arch)
cry_inc_dir = join(src_dir, 'crystax', 'include')
cry_lib_dir = join(src_dir, 'crystax', 'libs', arch.arch)
flags += ' -I{}'.format(py_inc_dir)
flags += ' -L{} -lpython{}m'.format(py_lib_dir, py_ver)
flags += " -I{}".format(cry_inc_dir)
flags += " -L{}".format(cry_lib_dir)

api_ver = self.ctx.android_api

platform = 'arm' if 'arm' in arch.arch else arch.arch
#: Not sure why but we have to inject these into the CC and LD env's for it to
#: use the correct arguments.
flags = " -L{ctx.ndk_dir}/platforms/android-{api_ver}/arch-{platform}/usr/lib/" \
" --sysroot={ctx.ndk_dir}/platforms/android-{api_ver}/arch-{platform}" \
.format(ctx=self.ctx, arch=arch, platform=platform, api_ver=api_ver,
py_so=py_so, py_ver=py_ver)
if flags not in env['CC']:
env['CC'] += flags
if flags not in env['LD']:
env['LD'] += flags + ' -shared'

return env

def prebuild_arch(self, arch):
Expand Down
49 changes: 41 additions & 8 deletions pythonforandroid/recipes/numpy/patches/ar.patch
Original file line number Diff line number Diff line change
@@ -1,11 +1,44 @@
--- a/numpy/distutils/unixccompiler.py 2015-02-01 17:38:21.000000000 +0100
+++ b/numpy/distutils/unixccompiler.py 2015-07-08 17:21:05.742468485 +0200
@@ -82,6 +82,8 @@
pass
self.mkpath(os.path.dirname(output_filename))
tmp_objects = objects + self.objects
+ from os import environ
+ self.archiver[0] = 'arm-linux-androideabi-ar'
diff --git a/numpy/core/code_generators/generate_umath.py b/numpy/core/code_generators/generate_umath.py
index 632bcb4..c1e0dd5 100644
--- a/numpy/core/code_generators/generate_umath.py
+++ b/numpy/core/code_generators/generate_umath.py
@@ -970,6 +970,7 @@ def make_arrays(funcdict):
funclist.append('%s_%s' % (tname, name))
if t.simd is not None:
for vt in t.simd:
+ continue
code2list.append(textwrap.dedent("""\
#ifdef HAVE_ATTRIBUTE_TARGET_{ISA}
if (npy_cpu_supports("{isa}")) {{
diff --git a/numpy/distutils/ccompiler.py b/numpy/distutils/ccompiler.py
index b03fb96..f9e6cd0 100644
--- a/numpy/distutils/ccompiler.py
+++ b/numpy/distutils/ccompiler.py
@@ -275,6 +275,7 @@ def CCompiler_compile(self, sources, output_dir=None, macros=None,
self._setup_compile(output_dir, macros, include_dirs, sources,
depends, extra_postargs)
cc_args = self._get_cc_args(pp_opts, debug, extra_preargs)
+ cc_args += os.environ['CFLAGS'].split()
display = "compile options: '%s'" % (' '.join(cc_args))
if extra_postargs:
display += "\nextra options: '%s'" % (' '.join(extra_postargs))
diff --git a/numpy/distutils/unixccompiler.py b/numpy/distutils/unixccompiler.py
index 11b2cce..f6dde79 100644
--- a/numpy/distutils/unixccompiler.py
+++ b/numpy/distutils/unixccompiler.py
@@ -54,6 +54,7 @@ def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts
deps = []

try:
+ self.linker_so = [os.environ['LD']+" "+os.environ['LDFLAGS']]
self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + deps +
extra_postargs, display = display)
except DistutilsExecError:
@@ -111,6 +112,7 @@ def UnixCCompiler_create_static_lib(self, objects, output_libname,
while tmp_objects:
objects = tmp_objects[:50]
tmp_objects = tmp_objects[50:]
+ self.archiver[0] = 'arm-linux-androideabi-ar'
display = '%s: adding %d object files to %s' % (
os.path.basename(self.archiver[0]),
len(objects), output_filename)
74 changes: 21 additions & 53 deletions pythonforandroid/recipes/numpy/patches/fix-numpy.patch
Original file line number Diff line number Diff line change
@@ -1,49 +1,17 @@
diff --git a/numpy/core/src/multiarray/numpyos.c b/numpy/core/src/multiarray/numpyos.c
index 44b32f4..378e199 100644
--- a/numpy/core/src/multiarray/numpyos.c
+++ b/numpy/core/src/multiarray/numpyos.c
@@ -165,8 +165,7 @@ ensure_decimal_point(char* buffer, size_t buf_size)
static void
change_decimal_from_locale_to_dot(char* buffer)
{
- struct lconv *locale_data = localeconv();
- const char *decimal_point = locale_data->decimal_point;
+ const char *decimal_point = ".";

if (decimal_point[0] != '.' || decimal_point[1] != 0) {
size_t decimal_point_len = strlen(decimal_point);
@@ -448,8 +447,7 @@ NumPyOS_ascii_strtod_plain(const char *s, char** endptr)
NPY_NO_EXPORT double
NumPyOS_ascii_strtod(const char *s, char** endptr)
{
- struct lconv *locale_data = localeconv();
- const char *decimal_point = locale_data->decimal_point;
+ const char *decimal_point = ".";
size_t decimal_point_len = strlen(decimal_point);

char buffer[FLOAT_FORMATBUFLEN+1];
diff --git a/numpy/core/src/private/npy_config.h b/numpy/core/src/private/npy_config.h
index f768c90..4e5d168 100644
--- a/numpy/core/src/private/npy_config.h
+++ b/numpy/core/src/private/npy_config.h
@@ -41,4 +41,10 @@
#undef HAVE_ATAN2
#endif

+/* Android only */
+#ifdef ANDROID
+#undef HAVE_LDEXPL
+#undef HAVE_FREXPL
+#endif
+
#endif
diff --git a/numpy/testing/__init__.py b/numpy/testing/__init__.py
index 258cbe9..ce4e0eb 100644
index a7c8593..007ce26 100644
--- a/numpy/testing/__init__.py
+++ b/numpy/testing/__init__.py
@@ -1,16 +1,7 @@
@@ -1,22 +1,8 @@
-"""Common test support for all numpy test scripts.
-
+# fake tester, android don't have unittest
+class Tester(object):
+ def test(self, *args, **kwargs):
+ pass
+ def bench(self, *args, **kwargs):
+ pass
+test = Tester().test

-This single module should provide all the common functionality for numpy tests
-in a single location, so that test scripts can just import it and work right
-away.
Expand All @@ -53,14 +21,14 @@ index 258cbe9..ce4e0eb 100644
-
-from unittest import TestCase
-
-from . import decorators as dec
-from .utils import *
-from .nosetester import NoseTester as Tester
-from .nosetester import run_module_suite
+# fake tester, android don't have unittest
+class Tester(object):
+ def test(self, *args, **kwargs):
+ pass
+ def bench(self, *args, **kwargs):
+ pass
test = Tester().test
-from ._private.utils import *
-from ._private import decorators as dec
-from ._private.nosetester import (
- run_module_suite, NoseTester as Tester
- )
-
-__all__ = _private.utils.__all__ + ['TestCase', 'run_module_suite']
-
-from ._private.pytesttester import PytestTester
-test = PytestTester(__name__)
-del PytestTester
60 changes: 32 additions & 28 deletions pythonforandroid/recipes/numpy/patches/lib.patch
Original file line number Diff line number Diff line change
@@ -1,39 +1,43 @@
--- a/numpy/linalg/setup.py 2015-07-09 14:15:59.850853336 +0200
+++ b/numpy/linalg/setup.py 2015-07-09 14:21:59.403889000 +0200
@@ -37,7 +37,8 @@
config.add_extension('lapack_lite',
sources = [get_lapack_lite_sources],
depends = ['lapack_litemodule.c'] + lapack_lite_src,
- extra_info = lapack_info
+ extra_info = lapack_info,
+ libraries = ['m'],
)

# umath_linalg module
@@ -46,7 +47,7 @@
sources = [get_lapack_lite_sources],
depends = ['umath_linalg.c.src'] + lapack_lite_src,
extra_info = lapack_info,
- libraries = ['npymath'],
+ libraries = ['npymath','m'],
)

return config
--- a/numpy/fft/setup.py 2015-07-09 14:35:22.299888028 +0200
+++ b/numpy/fft/setup.py 2015-07-09 14:33:54.858392578 +0200
@@ -9,7 +9,8 @@
diff --git a/numpy/fft/setup.py b/numpy/fft/setup.py
index cd99a82d7..e614ecd07 100644
--- a/numpy/fft/setup.py
+++ b/numpy/fft/setup.py
@@ -9,7 +9,8 @@ def configuration(parent_package='',top_path=None):

# Configure fftpack_lite
config.add_extension('fftpack_lite',
- sources=['fftpack_litemodule.c', 'fftpack.c']
+ sources=['fftpack_litemodule.c', 'fftpack.c'],
+ libraries = ['m']
+ libraries=['m']
)

return config
diff --git a/numpy/linalg/setup.py b/numpy/linalg/setup.py
index 66c07c9e1..d34bd930a 100644
--- a/numpy/linalg/setup.py
+++ b/numpy/linalg/setup.py
@@ -43,6 +43,7 @@ def configuration(parent_package='', top_path=None):
sources=['lapack_litemodule.c', get_lapack_lite_sources],
depends=['lapack_lite/f2c.h'],
extra_info=lapack_info,
+ libraries=['m'],
)

# umath_linalg module
@@ -51,7 +52,7 @@ def configuration(parent_package='', top_path=None):
sources=['umath_linalg.c.src', get_lapack_lite_sources],
depends=['lapack_lite/f2c.h'],
extra_info=lapack_info,
- libraries=['npymath'],
+ libraries=['npymath', 'm'],
)
return config

--- a/numpy/random/setup.orig.py 2015-07-09 14:44:41.105174826 +0200
+++ b/numpy/random/setup.py 2015-07-09 14:46:08.592679877 +0200
@@ -38,7 +38,7 @@
diff --git a/numpy/random/setup.py b/numpy/random/setup.py
index 3f3b773a4..c1db9f783 100644
--- a/numpy/random/setup.py
+++ b/numpy/random/setup.py
@@ -40,7 +40,7 @@ def configuration(parent_package='',top_path=None):
if needs_mingw_ftime_workaround():
defs.append(("NPY_NEEDS_MINGW_TIME_WORKAROUND", None))

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
diff --git a/numpy/distutils/system_info.py b/numpy/distutils/system_info.py
index a050430..471e958 100644
index bea120cf9..a448a83fc 100644
--- a/numpy/distutils/system_info.py
+++ b/numpy/distutils/system_info.py
@@ -610,6 +610,7 @@ class system_info:
@@ -719,6 +719,7 @@ class system_info(object):
return self.get_paths(self.section, key)

def get_libs(self, key, default):
Expand Down
69 changes: 69 additions & 0 deletions pythonforandroid/recipes/numpy/patches/python2-fixes.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c
index c70f852..695efd5 100644
--- a/numpy/core/src/multiarray/common.c
+++ b/numpy/core/src/multiarray/common.c
@@ -852,3 +852,12 @@ _may_have_objects(PyArray_Descr *dtype)
return (PyDataType_HASFIELDS(base) ||
PyDataType_FLAGCHK(base, NPY_ITEM_HASOBJECT) );
}
+
+/*
+ * Dummy to fix android NDK problem with missing reference.
+ */
+void *
+__emutls_get_address(struct __emutls_object *obj)
+{
+ return NULL;
+}
diff --git a/numpy/distutils/exec_command.py b/numpy/distutils/exec_command.py
index 8118e2f..b586442 100644
--- a/numpy/distutils/exec_command.py
+++ b/numpy/distutils/exec_command.py
@@ -260,7 +260,7 @@ def _exec_command(command, use_shell=None, use_tee = None, **env):
return 127, ''

text, err = proc.communicate()
- text = text.decode(locale.getpreferredencoding(False),
+ text = text.decode('UTF-8',
errors='replace')

text = text.replace('\r\n', '\n')
diff --git a/numpy/distutils/misc_util.py b/numpy/distutils/misc_util.py
index f2d677a..758b1ed 100644
--- a/numpy/distutils/misc_util.py
+++ b/numpy/distutils/misc_util.py
@@ -9,7 +9,6 @@ import atexit
import tempfile
import subprocess
import shutil
-import multiprocessing

import distutils
from distutils.errors import DistutilsError
@@ -93,10 +92,7 @@ def get_num_build_jobs():

"""
from numpy.distutils.core import get_distribution
- try:
- cpu_count = len(os.sched_getaffinity(0))
- except AttributeError:
- cpu_count = multiprocessing.cpu_count()
+ cpu_count = 1
envjobs = int(os.environ.get("NPY_NUM_BUILD_JOBS", cpu_count))
dist = get_distribution()
# may be None during configuration
diff --git a/setup.py b/setup.py
index fed178e..b0266eb 100755
--- a/setup.py
+++ b/setup.py
@@ -377,9 +377,8 @@ def setup_package():
# Raise errors for unsupported commands, improve help output, etc.
run_build = parse_setuppy_commands()

- from setuptools import setup
+ from numpy.distutils.core import setup
if run_build:
- from numpy.distutils.core import setup
cwd = os.path.abspath(os.path.dirname(__file__))
if not os.path.exists(os.path.join(cwd, 'PKG-INFO')):
# Generate Cython sources, unless building from source release