From 058fc8facea57bcc33847e0fda8df8fc9bcfd0bd Mon Sep 17 00:00:00 2001 From: kochelmonster Date: Tue, 17 May 2016 14:37:38 +0200 Subject: [PATCH 1/2] various recipes --- .../recipes/gevent-websocket/__init__.py | 11 ++ pythonforandroid/recipes/icu/__init__.py | 154 ++++++++++++++++++ .../recipes/msgpack-python/__init__.py | 12 ++ pythonforandroid/recipes/pyaml/__init__.py | 11 ++ pythonforandroid/recipes/pyicu/__init__.py | 59 +++++++ pythonforandroid/recipes/pyicu/icu.patch | 19 +++ pythonforandroid/recipes/pyicu/locale.patch | 12 ++ pythonforandroid/recipes/pyyaml/__init__.py | 11 ++ .../recipes/simple-crypt/__init__.py | 10 ++ pythonforandroid/recipes/ujson/__init__.py | 9 + pythonforandroid/recipes/wsaccel/__init__.py | 12 ++ 11 files changed, 320 insertions(+) create mode 100644 pythonforandroid/recipes/gevent-websocket/__init__.py create mode 100644 pythonforandroid/recipes/icu/__init__.py create mode 100644 pythonforandroid/recipes/msgpack-python/__init__.py create mode 100644 pythonforandroid/recipes/pyaml/__init__.py create mode 100644 pythonforandroid/recipes/pyicu/__init__.py create mode 100644 pythonforandroid/recipes/pyicu/icu.patch create mode 100644 pythonforandroid/recipes/pyicu/locale.patch create mode 100644 pythonforandroid/recipes/pyyaml/__init__.py create mode 100644 pythonforandroid/recipes/simple-crypt/__init__.py create mode 100644 pythonforandroid/recipes/ujson/__init__.py create mode 100644 pythonforandroid/recipes/wsaccel/__init__.py diff --git a/pythonforandroid/recipes/gevent-websocket/__init__.py b/pythonforandroid/recipes/gevent-websocket/__init__.py new file mode 100644 index 0000000000..a0bab42276 --- /dev/null +++ b/pythonforandroid/recipes/gevent-websocket/__init__.py @@ -0,0 +1,11 @@ +from pythonforandroid.toolchain import PythonRecipe + + +class GeventWebsocketRecipe(PythonRecipe): + version = '0.9.5' + url = 'https://pypi.python.org/packages/source/g/gevent-websocket/gevent-websocket-{version}.tar.gz' + depends = [('python2', 'python3crystax'), 'setuptools'] + site_packages_name = 'geventwebsocket' + call_hostpython_via_targetpython = False + +recipe = GeventWebsocketRecipe() diff --git a/pythonforandroid/recipes/icu/__init__.py b/pythonforandroid/recipes/icu/__init__.py new file mode 100644 index 0000000000..a2b731d2b2 --- /dev/null +++ b/pythonforandroid/recipes/icu/__init__.py @@ -0,0 +1,154 @@ +import sh +import os +from os.path import join, isdir +from pythonforandroid.recipe import NDKRecipe +from pythonforandroid.toolchain import shprint, info +from pythonforandroid.util import current_directory, ensure_dir + + +class ICURecipe(NDKRecipe): + name = 'icu4c' + version = '57.1' + url = 'http://download.icu-project.org/files/icu4c/57.1/icu4c-57_1-src.tgz' + + depends = [('python2', 'python3crystax')] # installs in python + generated_libraries = [ + 'libicui18n.so', 'libicuuc.so', 'libicudata.so', 'libicule.so'] + + def get_lib_dir(self, arch): + lib_dir = join(self.ctx.get_python_install_dir(), "lib") + ensure_dir(lib_dir) + return lib_dir + + def prepare_build_dir(self, arch): + if self.ctx.android_api > 19: + # greater versions do not have /usr/include/sys/exec_elf.h + raise RuntimeError("icu needs an android api <= 19") + + super(ICURecipe, self).prepare_build_dir(arch) + + def build_arch(self, arch, *extra_args): + env = self.get_recipe_env(arch).copy() + build_root = self.get_build_dir(arch.arch) + + def make_build_dest(dest): + build_dest = join(build_root, dest) + if not isdir(build_dest): + ensure_dir(build_dest) + return build_dest, False + + return build_dest, True + + icu_build = join(build_root, "icu_build") + build_linux, exists = make_build_dest("build_icu_linux") + + host_env = os.environ.copy() + # reduce the function set + host_env["CPPFLAGS"] = ( + "-O3 -fno-short-wchar -DU_USING_ICU_NAMESPACE=1 -fno-short-enums " + "-DU_HAVE_NL_LANGINFO_CODESET=0 -D__STDC_INT64__ -DU_TIMEZONE=0 " + "-DUCONFIG_NO_LEGACY_CONVERSION=1 " + "-DUCONFIG_NO_TRANSLITERATION=0 ") + + if not exists: + configure = sh.Command( + join(build_root, "source", "runConfigureICU")) + with current_directory(build_linux): + shprint( + configure, + "Linux", + "--prefix="+icu_build, + "--enable-extras=no", + "--enable-strict=no", + "--enable-static", + "--enable-tests=no", + "--enable-samples=no", + _env=host_env) + shprint(sh.make, "-j5", _env=host_env) + shprint(sh.make, "install", _env=host_env) + + build_android, exists = make_build_dest("build_icu_android") + if exists: + return + + configure = sh.Command(join(build_root, "source", "configure")) + + include = ( + " -I{ndk}/sources/cxx-stl/gnu-libstdc++/{version}/include/" + " -I{ndk}/sources/cxx-stl/gnu-libstdc++/{version}/libs/" + "{arch}/include") + include = include.format(ndk=self.ctx.ndk_dir, + version=env["TOOLCHAIN_VERSION"], + arch=arch.arch) + env["CPPFLAGS"] = env["CXXFLAGS"] + " " + env["CPPFLAGS"] += host_env["CPPFLAGS"] + env["CPPFLAGS"] += include + + lib = "{ndk}/sources/cxx-stl/gnu-libstdc++/{version}/libs/{arch}" + lib = lib.format(ndk=self.ctx.ndk_dir, + version=env["TOOLCHAIN_VERSION"], + arch=arch.arch) + env["LDFLAGS"] += " -lgnustl_shared -L"+lib + + env.pop("CFLAGS", None) + env.pop("CXXFLAGS", None) + + with current_directory(build_android): + shprint( + configure, + "--with-cross-build="+build_linux, + "--enable-extras=no", + "--enable-strict=no", + "--enable-static", + "--enable-tests=no", + "--enable-samples=no", + "--host="+env["TOOLCHAIN_PREFIX"], + "--prefix="+icu_build, + _env=env) + shprint(sh.make, "-j5", _env=env) + shprint(sh.make, "install", _env=env) + + self.copy_files(arch) + + def copy_files(self, arch): + ndk = self.ctx.ndk_dir + env = self.get_recipe_env(arch) + + lib = "{ndk}/sources/cxx-stl/gnu-libstdc++/{version}/libs/{arch}" + lib = lib.format(ndk=self.ctx.ndk_dir, + version=env["TOOLCHAIN_VERSION"], + arch=arch.arch) + stl_lib = join(lib, "libgnustl_shared.so") + dst_dir = join(self.ctx.get_site_packages_dir(), "..", "lib-dynload") + shprint(sh.cp, stl_lib, dst_dir) + + src_lib = join(self.get_build_dir(arch.arch), "icu_build", "lib") + dst_lib = self.get_lib_dir(arch) + + src_suffix = "." + self.version + dst_suffix = "." + self.version.split(".")[0] # main version + for lib in self.generated_libraries: + shprint(sh.cp, join(src_lib, lib+src_suffix), + join(dst_lib, lib+dst_suffix)) + + src_include = join( + self.get_build_dir(arch.arch), "icu_build", "include") + dst_include = join( + self.ctx.get_python_install_dir(), "include", "icu") + ensure_dir(dst_include) + shprint(sh.cp, "-r", join(src_include, "layout"), dst_include) + shprint(sh.cp, "-r", join(src_include, "unicode"), dst_include) + + # copy stl library + lib = "{ndk}/sources/cxx-stl/gnu-libstdc++/{version}/libs/{arch}" + lib = lib.format(ndk=self.ctx.ndk_dir, + version=env["TOOLCHAIN_VERSION"], + arch=arch.arch) + stl_lib = join(lib, "libgnustl_shared.so") + + dst_dir = join(self.ctx.get_python_install_dir(), "lib") + ensure_dir(dst_dir) + shprint(sh.cp, stl_lib, dst_dir) + + +recipe = ICURecipe() diff --git a/pythonforandroid/recipes/msgpack-python/__init__.py b/pythonforandroid/recipes/msgpack-python/__init__.py new file mode 100644 index 0000000000..393e6b40ba --- /dev/null +++ b/pythonforandroid/recipes/msgpack-python/__init__.py @@ -0,0 +1,12 @@ +import os +import sh +from pythonforandroid.recipe import CythonRecipe + + +class MsgPackRecipe(CythonRecipe): + version = '0.4.7' + url = 'https://pypi.python.org/packages/source/m/msgpack-python/msgpack-python-{version}.tar.gz' + depends = [('python2', 'python3crystax'), "setuptools"] + call_hostpython_via_targetpython = False + +recipe = MsgPackRecipe() diff --git a/pythonforandroid/recipes/pyaml/__init__.py b/pythonforandroid/recipes/pyaml/__init__.py new file mode 100644 index 0000000000..d3d1eb9102 --- /dev/null +++ b/pythonforandroid/recipes/pyaml/__init__.py @@ -0,0 +1,11 @@ +from pythonforandroid.toolchain import PythonRecipe + + +class PyamlRecipe(PythonRecipe): + version = "15.8.2" + url = 'https://pypi.python.org/packages/source/p/pyaml/pyaml-{version}.tar.gz' + depends = [('python2', 'python3crystax'), "setuptools"] + site_packages_name = 'yaml' + call_hostpython_via_targetpython = False + +recipe = PyamlRecipe() diff --git a/pythonforandroid/recipes/pyicu/__init__.py b/pythonforandroid/recipes/pyicu/__init__.py new file mode 100644 index 0000000000..3e6627e17c --- /dev/null +++ b/pythonforandroid/recipes/pyicu/__init__.py @@ -0,0 +1,59 @@ +import os +import sh +from os.path import join +from pythonforandroid.recipe import CompiledComponentsPythonRecipe +from pythonforandroid.util import current_directory +from pythonforandroid.toolchain import shprint, info + + +class PyICURecipe(CompiledComponentsPythonRecipe): + version = '1.9.2' + url = 'https://pypi.python.org/packages/source/P/PyICU/PyICU-{version}.tar.gz' + depends = [('python2', 'python3crystax'), "icu"] + patches = ['locale.patch', 'icu.patch'] + + def get_recipe_env(self, arch): + env = super(PyICURecipe, self).get_recipe_env(arch) + + icu_include = join( + self.ctx.get_python_install_dir(), "include", "icu") + + env["CC"] += " -I"+icu_include + + include = ( + " -I{ndk}/sources/cxx-stl/gnu-libstdc++/{version}/include/" + " -I{ndk}/sources/cxx-stl/gnu-libstdc++/{version}/libs/" + "{arch}/include") + include = include.format(ndk=self.ctx.ndk_dir, + version=env["TOOLCHAIN_VERSION"], + arch=arch.arch) + env["CC"] += include + + lib = "{ndk}/sources/cxx-stl/gnu-libstdc++/{version}/libs/{arch}" + lib = lib.format(ndk=self.ctx.ndk_dir, + version=env["TOOLCHAIN_VERSION"], + arch=arch.arch) + env["LDFLAGS"] += " -lgnustl_shared -L"+lib + + build_dir = self.get_build_dir(arch.arch) + env["LDFLAGS"] += " -L"+build_dir + return env + + def build_arch(self, arch): + build_dir = self.get_build_dir(arch.arch) + + info("create links to icu libs") + lib_dir = join(self.ctx.get_python_install_dir(), "lib") + icu_libs = [f for f in os.listdir(lib_dir) if f.startswith("libicu")] + + for l in icu_libs: + raw = l.rsplit(".", 1)[0] + try: + shprint(sh.ln, "-s", join(lib_dir, l), join(build_dir, raw)) + except Exception: + pass + + super(PyICURecipe, self).build_arch(arch) + + +recipe = PyICURecipe() diff --git a/pythonforandroid/recipes/pyicu/icu.patch b/pythonforandroid/recipes/pyicu/icu.patch new file mode 100644 index 0000000000..e0a42fc4ef --- /dev/null +++ b/pythonforandroid/recipes/pyicu/icu.patch @@ -0,0 +1,19 @@ +diff -Naur icu.py icu1.py +--- pyicu/icu.py 2012-11-23 21:28:55.000000000 +0100 ++++ icu1.py 2016-05-14 14:45:44.160023949 +0200 +@@ -34,4 +34,15 @@ + class InvalidArgsError(Exception): + pass + ++import ctypes ++import os ++root = os.environ["ANDROID_APP_PATH"] ++ctypes.cdll.LoadLibrary(os.path.join(root, "lib", "libgnustl_shared.so")) ++ctypes.cdll.LoadLibrary(os.path.join(root, "lib", "libicudata.so.57")) ++ctypes.cdll.LoadLibrary(os.path.join(root, "lib", "libicuuc.so.57")) ++ctypes.cdll.LoadLibrary(os.path.join(root, "lib", "libicui18n.so.57")) ++ctypes.cdll.LoadLibrary(os.path.join(root, "lib", "libicule.so.57")) ++del root ++del os ++ + from docs import * diff --git a/pythonforandroid/recipes/pyicu/locale.patch b/pythonforandroid/recipes/pyicu/locale.patch new file mode 100644 index 0000000000..b291c30c37 --- /dev/null +++ b/pythonforandroid/recipes/pyicu/locale.patch @@ -0,0 +1,12 @@ +diff -Naur locale.cpp locale1.cpp +--- pyicu/locale.cpp 2015-04-29 07:32:39.000000000 +0200 ++++ locale1.cpp 2016-05-12 17:13:08.990059346 +0200 +@@ -27,7 +27,7 @@ + #if defined(_MSC_VER) || defined(__WIN32) + #include + #else +-#include ++#include + #include + #include + #endif diff --git a/pythonforandroid/recipes/pyyaml/__init__.py b/pythonforandroid/recipes/pyyaml/__init__.py new file mode 100644 index 0000000000..188397ad04 --- /dev/null +++ b/pythonforandroid/recipes/pyyaml/__init__.py @@ -0,0 +1,11 @@ +from pythonforandroid.toolchain import PythonRecipe + + +class PyYamlRecipe(PythonRecipe): + version = "3.11" + url = 'http://pyyaml.org/download/pyyaml/PyYAML-{version}.tar.gz' + depends = [('python2', 'python3crystax'), "setuptools"] + site_packages_name = 'pyyaml' + call_hostpython_via_targetpython = False + +recipe = PyYamlRecipe() diff --git a/pythonforandroid/recipes/simple-crypt/__init__.py b/pythonforandroid/recipes/simple-crypt/__init__.py new file mode 100644 index 0000000000..c57c5136f4 --- /dev/null +++ b/pythonforandroid/recipes/simple-crypt/__init__.py @@ -0,0 +1,10 @@ +from pythonforandroid.toolchain import PythonRecipe + + +class SimpleCryptRecipe(PythonRecipe): + version = '4.1.7' + url = 'https://pypi.python.org/packages/source/s/simple-crypt/simple-crypt-{version}.tar.gz' + depends = [('python2', 'python3crystax'), 'pycrypto'] + site_packages_name = 'simplecrypt' + +recipe = SimpleCryptRecipe() diff --git a/pythonforandroid/recipes/ujson/__init__.py b/pythonforandroid/recipes/ujson/__init__.py new file mode 100644 index 0000000000..4cccc094ef --- /dev/null +++ b/pythonforandroid/recipes/ujson/__init__.py @@ -0,0 +1,9 @@ +from pythonforandroid.toolchain import CompiledComponentsPythonRecipe + + +class UJsonRecipe(CompiledComponentsPythonRecipe): + version = '1.35' + url = 'https://pypi.python.org/packages/source/u/ujson/ujson-{version}.tar.gz' + depends = [('python2', 'python3crystax')] + +recipe = UJsonRecipe() diff --git a/pythonforandroid/recipes/wsaccel/__init__.py b/pythonforandroid/recipes/wsaccel/__init__.py new file mode 100644 index 0000000000..ad257b8e6b --- /dev/null +++ b/pythonforandroid/recipes/wsaccel/__init__.py @@ -0,0 +1,12 @@ +import os +import sh +from pythonforandroid.recipe import CythonRecipe + + +class WSAccellRecipe(CythonRecipe): + version = '0.6.2' + url = 'https://pypi.python.org/packages/source/w/wsaccel/wsaccel-{version}.tar.gz' + depends = [('python2', 'python3crystax')] + call_hostpython_via_targetpython = False + +recipe = WSAccellRecipe() From a621211fc5054fb1ebef9669509a82de78b558a2 Mon Sep 17 00:00:00 2001 From: bobatsar Date: Fri, 20 May 2016 16:20:46 +0200 Subject: [PATCH 2/2] allow local_recipes with a relative path local_recipes were only working if an absolute path was given --- pythonforandroid/recipe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pythonforandroid/recipe.py b/pythonforandroid/recipe.py index 5f2105dbe8..97e7f076db 100644 --- a/pythonforandroid/recipe.py +++ b/pythonforandroid/recipe.py @@ -580,7 +580,7 @@ def has_libs(self, arch, *libs): def recipe_dirs(cls, ctx): recipe_dirs = [] if ctx.local_recipes is not None: - recipe_dirs.append(ctx.local_recipes) + recipe_dirs.append(realpath(ctx.local_recipes)) if ctx.storage_dir: recipe_dirs.append(join(ctx.storage_dir, 'recipes')) recipe_dirs.append(join(ctx.root_dir, "recipes"))