Skip to content
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

Added a matplotlib recipe #1822

Merged
merged 16 commits into from
Jun 3, 2019
Merged
Show file tree
Hide file tree
Changes from 15 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
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ protected static ArrayList<String> getLibraries(File libsDir) {
addLibraryIfExists(libsList, "crystax", libsDir);
addLibraryIfExists(libsList, "sqlite3", libsDir);
addLibraryIfExists(libsList, "ffi", libsDir);
addLibraryIfExists(libsList, "png16", libsDir);
libsList.add("SDL2");
libsList.add("SDL2_image");
libsList.add("SDL2_mixer");
Expand Down
6 changes: 3 additions & 3 deletions pythonforandroid/recipes/Pillow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ def get_recipe_env(self, arch=None, with_flags_in_cc=True):
ndk_include_dir = join(self.ctx.ndk_dir, 'sysroot', 'usr', 'include')

png = self.get_recipe('png', self.ctx)
png_lib_dir = png.get_lib_dir(arch)
png_jni_dir = png.get_jni_dir(arch)
png_lib_dir = join(png.get_build_dir(arch.arch), '.libs')
png_inc_dir = png.get_build_dir(arch)

jpeg = self.get_recipe('jpeg', self.ctx)
jpeg_inc_dir = jpeg_lib_dir = jpeg.get_build_dir(arch.arch)
Expand All @@ -41,7 +41,7 @@ def get_recipe_env(self, arch=None, with_flags_in_cc=True):
env['FREETYPE_ROOT'] = '{}|{}'.format(free_lib_dir, free_inc_dir)
env['ZLIB_ROOT'] = '{}|{}'.format(ndk_lib_dir, ndk_include_dir)

cflags = ' -I{}'.format(png_jni_dir)
cflags = ' -I{}'.format(png_inc_dir)
cflags += ' -I{} -I{}'.format(harf_inc_dir, join(harf_inc_dir, 'src'))
cflags += ' -I{}'.format(free_inc_dir)
cflags += ' -I{}'.format(jpeg_inc_dir)
Expand Down
33 changes: 33 additions & 0 deletions pythonforandroid/recipes/matplotlib/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

from pythonforandroid.recipe import CppCompiledComponentsPythonRecipe, warning, Recipe

from os.path import join
import shutil

class MatplotlibRecipe(CppCompiledComponentsPythonRecipe):

version = '3.0.3'
url = 'https://github.com/matplotlib/matplotlib/archive/v{version}.zip'

depends = ['numpy', 'png', 'setuptools', 'freetype', 'kiwisolver']

python_depends = ['pyparsing', 'cycler', 'python-dateutil']

# We need to patch to:
# - make mpl build against the same numpy version as the numpy recipe
# (this could be done better by setting the target version dynamically)
# - prevent mpl trying to build TkAgg, which wouldn't work on Android anyway but has build issues
patches = ['mpl_android_fixes.patch']

call_hostpython_via_targetpython = False

def prebuild_arch(self, arch):
with open(join(self.get_recipe_dir(), 'setup.cfg.template')) as fileh:
setup_cfg = fileh.read()

with open(join(self.get_build_dir(arch), 'setup.cfg'), 'w') as fileh:
fileh.write(setup_cfg.format(
ndk_sysroot_usr=join(self.ctx.ndk_dir, 'sysroot', 'usr')))


recipe = MatplotlibRecipe()
29 changes: 29 additions & 0 deletions pythonforandroid/recipes/matplotlib/mpl_android_fixes.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
diff --git a/setupext.py b/setupext.py
index fc82d5d..2067db0 100644
--- a/setupext.py
+++ b/setupext.py
@@ -1004,10 +1004,10 @@ class Numpy(SetupPackage):
ext.define_macros.append(('__STDC_FORMAT_MACROS', 1))

def get_setup_requires(self):
- return ['numpy>=1.10.0']
+ return ['numpy==1.15.1'] # to match p4a's target version

def get_install_requires(self):
- return ['numpy>=1.10.0']
+ return ['numpy==1.15.1'] # to match p4a's target version


class LibAgg(SetupPackage):
@@ -1443,9 +1443,10 @@ class BackendAgg(OptionalBackendPackage):

class BackendTkAgg(OptionalBackendPackage):
name = "tkagg"
- force = True
+ force = False

def check(self):
+ raise CheckFailed("Disabled by patching during Android build") # tk doesn't work on Android but causes build problems
return "installing; run-time loading from Python Tcl / Tk"

def get_extension(self):
93 changes: 93 additions & 0 deletions pythonforandroid/recipes/matplotlib/setup.cfg.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Rename this file to setup.cfg to modify Matplotlib's
# build options.

[egg_info]

[directories]
# Uncomment to override the default basedir in setupext.py.
# This can be a single directory or a comma-delimited list of directories.
basedirlist = {ndk_sysroot_usr}

[test]
# If you plan to develop Matplotlib and run or add to the test suite,
# set this to True. It will download and build a specific version of
# FreeType, and then use that to build the ft2font extension. This
# ensures that test images are exactly reproducible.
# local_freetype = True

[status]
# To suppress display of the dependencies and their versions
# at the top of the build log, uncomment the following line:
#suppress = True

[packages]
# There are a number of subpackages of Matplotlib that are considered
# optional. All except tests are installed by default, but that can
# be changed here.
#
tests = False
sample_data = False
#toolkits = True
# Tests for the toolkits are only automatically installed
# if the tests and toolkits packages are also getting installed.
toolkits_tests = False

[gui_support]
# Matplotlib supports multiple GUI toolkits, including
# GTK3, MacOSX, Qt4, Qt5, Tk, and WX. Support for many of
# these toolkits requires AGG, the Anti-Grain Geometry library,
# which is provided by Matplotlib and built by default.
#
# Some backends are written in pure Python, and others require
# extension code to be compiled. By default, Matplotlib checks for
# these GUI toolkits during installation and, if present, compiles the
# required extensions to support the toolkit.
#
# - Tk support requires Tk development headers and Tkinter.
# - Mac OSX backend requires the Cocoa headers included with XCode.
# - Windowing is MS-Windows specific, and requires the "windows.h"
# header.
#
# The other GUI toolkits do not require any extension code, and can be
# used as long as the libraries are installed on your system --
# therefore they are installed unconditionally.
#
# You can uncomment any the following lines to change this
# behavior. Acceptable values are:
#
# True: build the extension. Exits with a warning if the
# required dependencies are not available
# False: do not build the extension
# auto: build if the required dependencies are available,
# otherwise skip silently. This is the default
# behavior
#
agg = True
cairo = False
gtk3agg = False
gtk3cairo = False
macosx = False
pyside = False
qt4agg = False
tkagg = False
windowing = False
wxagg = False

[rc_options]
# User-configurable options
#
# Default backend, one of: Agg, Cairo, GTK3Agg, GTK3Cairo, MacOSX, Pdf, Ps,
# Qt4Agg, Qt5Agg, SVG, TkAgg, WX, WXAgg.
#
# The Agg, Ps, Pdf and SVG backends do not require external dependencies. Do
# not choose MacOSX, or TkAgg if you have disabled the relevant extension
# modules. Agg will be used by default.
#
backend = Agg
#

[package_data]
# Package additional files found in the lib/matplotlib directories.
#
# On Windows, package DLL files.
#dlls = True
91 changes: 17 additions & 74 deletions pythonforandroid/recipes/pil/__init__.py
Original file line number Diff line number Diff line change
@@ -1,79 +1,22 @@
from os.path import join, exists
from pythonforandroid.recipe import CompiledComponentsPythonRecipe
from pythonforandroid.toolchain import shprint
import sh
from pythonforandroid.recipes.Pillow import PillowRecipe
from pythonforandroid.logger import warning

class PilRecipe(PillowRecipe):
"""A transparent wrapper around the Pillow recipe, it should build
Pillow automatically as if "pillow" were specified in the
requirements.
"""

name = 'Pillow' # ensures the Pillow recipe directory is used where necessary

class PILRecipe(CompiledComponentsPythonRecipe):
name = 'pil'
version = '1.1.7'
url = 'http://effbot.org/downloads/Imaging-{version}.tar.gz'
depends = ['png', 'jpeg', 'setuptools']
opt_depends = ['freetype']
site_packages_name = 'PIL'
conflicts = ['pillow']

patches = ['disable-tk.patch',
'fix-directories.patch']
def build_arch(self, arch):
warning('PIL is no longer supported, building Pillow instead. '
'This should be a drop-in replacement.')
warning('It is recommended to change "pil" to "pillow" in your requirements, '
'to ensure future compatibility')
super(PilRecipe, self).build_arch(arch)

def get_recipe_env(self, arch=None, with_flags_in_cc=True):
env = super(PILRecipe, self).get_recipe_env(arch, with_flags_in_cc)

env['PYTHON_INCLUDE_ROOT'] = self.ctx.python_recipe.include_root(arch.arch)
env['PYTHON_LINK_ROOT'] = self.ctx.python_recipe.link_root(arch.arch)

ndk_lib_dir = join(self.ctx.ndk_platform, 'usr', 'lib')
ndk_include_dir = join(self.ctx.ndk_dir, 'sysroot', 'usr', 'include')

png = self.get_recipe('png', self.ctx)
png_lib_dir = png.get_lib_dir(arch)
png_jni_dir = png.get_jni_dir(arch)

jpeg = self.get_recipe('jpeg', self.ctx)
jpeg_inc_dir = jpeg_lib_dir = jpeg.get_build_dir(arch.arch)

if 'freetype' in self.ctx.recipe_build_order:
freetype = self.get_recipe('freetype', self.ctx)
free_lib_dir = join(freetype.get_build_dir(arch.arch), 'objs', '.libs')
free_inc_dir = join(freetype.get_build_dir(arch.arch), 'include')
# hack freetype to be found by pil
freetype_link = join(free_inc_dir, 'freetype')
if not exists(freetype_link):
shprint(sh.ln, '-s', join(free_inc_dir), freetype_link)

harfbuzz = self.get_recipe('harfbuzz', self.ctx)
harf_lib_dir = join(harfbuzz.get_build_dir(arch.arch), 'src', '.libs')
harf_inc_dir = harfbuzz.get_build_dir(arch.arch)

env['FREETYPE_ROOT'] = '{}|{}'.format(free_lib_dir, free_inc_dir)

env['JPEG_ROOT'] = '{}|{}'.format(jpeg_lib_dir, jpeg_inc_dir)
env['ZLIB_ROOT'] = '{}|{}'.format(ndk_lib_dir, ndk_include_dir)

cflags = ' -std=c99'
cflags += ' -I{}'.format(png_jni_dir)
if 'freetype' in self.ctx.recipe_build_order:
cflags += ' -I{} -I{}'.format(harf_inc_dir, join(harf_inc_dir, 'src'))
cflags += ' -I{}'.format(free_inc_dir)
cflags += ' -I{}'.format(jpeg_inc_dir)
cflags += ' -I{}'.format(ndk_include_dir)

py_v = self.ctx.python_recipe.major_minor_version_string
if py_v[0] == '3':
py_v += 'm'

env['LIBS'] = ' -lpython{version} -lpng'.format(version=py_v)
if 'freetype' in self.ctx.recipe_build_order:
env['LIBS'] += ' -lfreetype -lharfbuzz'
env['LIBS'] += ' -ljpeg -lturbojpeg'

env['LDFLAGS'] += ' -L{} -L{}'.format(env['PYTHON_LINK_ROOT'], png_lib_dir)
if 'freetype' in self.ctx.recipe_build_order:
env['LDFLAGS'] += ' -L{} -L{}'.format(harf_lib_dir, free_lib_dir)
env['LDFLAGS'] += ' -L{} -L{}'.format(jpeg_lib_dir, ndk_lib_dir)

if cflags not in env['CFLAGS']:
env['CFLAGS'] += cflags
return env


recipe = PILRecipe()
recipe = PilRecipe()
12 changes: 0 additions & 12 deletions pythonforandroid/recipes/pil/disable-tk.patch

This file was deleted.

85 changes: 0 additions & 85 deletions pythonforandroid/recipes/pil/fix-directories.patch

This file was deleted.

Loading