Skip to content

Commit 3658089

Browse files
authored
Merge pull request #1822 from inclement/matplotlib_recipe
Added a matplotlib recipe
2 parents ff42ca5 + f7f0451 commit 3658089

File tree

13 files changed

+341
-184
lines changed

13 files changed

+341
-184
lines changed

pythonforandroid/bootstraps/sdl2/build/src/main/java/org/kivy/android/PythonUtil.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ protected static ArrayList<String> getLibraries(File libsDir) {
3434
addLibraryIfExists(libsList, "crystax", libsDir);
3535
addLibraryIfExists(libsList, "sqlite3", libsDir);
3636
addLibraryIfExists(libsList, "ffi", libsDir);
37+
addLibraryIfExists(libsList, "png16", libsDir);
3738
libsList.add("SDL2");
3839
libsList.add("SDL2_image");
3940
libsList.add("SDL2_mixer");

pythonforandroid/recipes/Pillow/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ def get_recipe_env(self, arch=None, with_flags_in_cc=True):
2121
ndk_include_dir = join(self.ctx.ndk_dir, 'sysroot', 'usr', 'include')
2222

2323
png = self.get_recipe('png', self.ctx)
24-
png_lib_dir = png.get_lib_dir(arch)
25-
png_jni_dir = png.get_jni_dir(arch)
24+
png_lib_dir = join(png.get_build_dir(arch.arch), '.libs')
25+
png_inc_dir = png.get_build_dir(arch)
2626

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

44-
cflags = ' -I{}'.format(png_jni_dir)
44+
cflags = ' -I{}'.format(png_inc_dir)
4545
cflags += ' -I{} -I{}'.format(harf_inc_dir, join(harf_inc_dir, 'src'))
4646
cflags += ' -I{}'.format(free_inc_dir)
4747
cflags += ' -I{}'.format(jpeg_inc_dir)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
from pythonforandroid.recipe import CppCompiledComponentsPythonRecipe
3+
4+
from os.path import join
5+
6+
7+
class MatplotlibRecipe(CppCompiledComponentsPythonRecipe):
8+
9+
version = '3.0.3'
10+
url = 'https://github.com/matplotlib/matplotlib/archive/v{version}.zip'
11+
12+
depends = ['numpy', 'png', 'setuptools', 'freetype', 'kiwisolver']
13+
14+
python_depends = ['pyparsing', 'cycler', 'python-dateutil']
15+
16+
# We need to patch to:
17+
# - make mpl build against the same numpy version as the numpy recipe
18+
# (this could be done better by setting the target version dynamically)
19+
# - prevent mpl trying to build TkAgg, which wouldn't work on Android anyway but has build issues
20+
patches = ['mpl_android_fixes.patch']
21+
22+
call_hostpython_via_targetpython = False
23+
24+
def prebuild_arch(self, arch):
25+
with open(join(self.get_recipe_dir(), 'setup.cfg.template')) as fileh:
26+
setup_cfg = fileh.read()
27+
28+
with open(join(self.get_build_dir(arch), 'setup.cfg'), 'w') as fileh:
29+
fileh.write(setup_cfg.format(
30+
ndk_sysroot_usr=join(self.ctx.ndk_dir, 'sysroot', 'usr')))
31+
32+
33+
recipe = MatplotlibRecipe()
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
diff --git a/setupext.py b/setupext.py
2+
index fc82d5d..2067db0 100644
3+
--- a/setupext.py
4+
+++ b/setupext.py
5+
@@ -1004,10 +1004,10 @@ class Numpy(SetupPackage):
6+
ext.define_macros.append(('__STDC_FORMAT_MACROS', 1))
7+
8+
def get_setup_requires(self):
9+
- return ['numpy>=1.10.0']
10+
+ return ['numpy==1.15.1'] # to match p4a's target version
11+
12+
def get_install_requires(self):
13+
- return ['numpy>=1.10.0']
14+
+ return ['numpy==1.15.1'] # to match p4a's target version
15+
16+
17+
class LibAgg(SetupPackage):
18+
@@ -1443,9 +1443,10 @@ class BackendAgg(OptionalBackendPackage):
19+
20+
class BackendTkAgg(OptionalBackendPackage):
21+
name = "tkagg"
22+
- force = True
23+
+ force = False
24+
25+
def check(self):
26+
+ raise CheckFailed("Disabled by patching during Android build") # tk doesn't work on Android but causes build problems
27+
return "installing; run-time loading from Python Tcl / Tk"
28+
29+
def get_extension(self):
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Rename this file to setup.cfg to modify Matplotlib's
2+
# build options.
3+
4+
[egg_info]
5+
6+
[directories]
7+
# Uncomment to override the default basedir in setupext.py.
8+
# This can be a single directory or a comma-delimited list of directories.
9+
basedirlist = {ndk_sysroot_usr}
10+
11+
[test]
12+
# If you plan to develop Matplotlib and run or add to the test suite,
13+
# set this to True. It will download and build a specific version of
14+
# FreeType, and then use that to build the ft2font extension. This
15+
# ensures that test images are exactly reproducible.
16+
# local_freetype = True
17+
18+
[status]
19+
# To suppress display of the dependencies and their versions
20+
# at the top of the build log, uncomment the following line:
21+
#suppress = True
22+
23+
[packages]
24+
# There are a number of subpackages of Matplotlib that are considered
25+
# optional. All except tests are installed by default, but that can
26+
# be changed here.
27+
#
28+
tests = False
29+
sample_data = False
30+
#toolkits = True
31+
# Tests for the toolkits are only automatically installed
32+
# if the tests and toolkits packages are also getting installed.
33+
toolkits_tests = False
34+
35+
[gui_support]
36+
# Matplotlib supports multiple GUI toolkits, including
37+
# GTK3, MacOSX, Qt4, Qt5, Tk, and WX. Support for many of
38+
# these toolkits requires AGG, the Anti-Grain Geometry library,
39+
# which is provided by Matplotlib and built by default.
40+
#
41+
# Some backends are written in pure Python, and others require
42+
# extension code to be compiled. By default, Matplotlib checks for
43+
# these GUI toolkits during installation and, if present, compiles the
44+
# required extensions to support the toolkit.
45+
#
46+
# - Tk support requires Tk development headers and Tkinter.
47+
# - Mac OSX backend requires the Cocoa headers included with XCode.
48+
# - Windowing is MS-Windows specific, and requires the "windows.h"
49+
# header.
50+
#
51+
# The other GUI toolkits do not require any extension code, and can be
52+
# used as long as the libraries are installed on your system --
53+
# therefore they are installed unconditionally.
54+
#
55+
# You can uncomment any the following lines to change this
56+
# behavior. Acceptable values are:
57+
#
58+
# True: build the extension. Exits with a warning if the
59+
# required dependencies are not available
60+
# False: do not build the extension
61+
# auto: build if the required dependencies are available,
62+
# otherwise skip silently. This is the default
63+
# behavior
64+
#
65+
agg = True
66+
cairo = False
67+
gtk3agg = False
68+
gtk3cairo = False
69+
macosx = False
70+
pyside = False
71+
qt4agg = False
72+
tkagg = False
73+
windowing = False
74+
wxagg = False
75+
76+
[rc_options]
77+
# User-configurable options
78+
#
79+
# Default backend, one of: Agg, Cairo, GTK3Agg, GTK3Cairo, MacOSX, Pdf, Ps,
80+
# Qt4Agg, Qt5Agg, SVG, TkAgg, WX, WXAgg.
81+
#
82+
# The Agg, Ps, Pdf and SVG backends do not require external dependencies. Do
83+
# not choose MacOSX, or TkAgg if you have disabled the relevant extension
84+
# modules. Agg will be used by default.
85+
#
86+
backend = Agg
87+
#
88+
89+
[package_data]
90+
# Package additional files found in the lib/matplotlib directories.
91+
#
92+
# On Windows, package DLL files.
93+
#dlls = True
Lines changed: 16 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,23 @@
1-
from os.path import join, exists
2-
from pythonforandroid.recipe import CompiledComponentsPythonRecipe
3-
from pythonforandroid.toolchain import shprint
4-
import sh
1+
from pythonforandroid.recipes.Pillow import PillowRecipe
2+
from pythonforandroid.logger import warning
53

64

7-
class PILRecipe(CompiledComponentsPythonRecipe):
8-
name = 'pil'
9-
version = '1.1.7'
10-
url = 'http://effbot.org/downloads/Imaging-{version}.tar.gz'
11-
depends = ['png', 'jpeg', 'setuptools']
12-
opt_depends = ['freetype']
13-
site_packages_name = 'PIL'
5+
class PilRecipe(PillowRecipe):
6+
"""A transparent wrapper around the Pillow recipe, it should build
7+
Pillow automatically as if "pillow" were specified in the
8+
requirements.
9+
"""
1410

15-
patches = ['disable-tk.patch',
16-
'fix-directories.patch']
11+
name = 'Pillow' # ensures the Pillow recipe directory is used where necessary
1712

18-
def get_recipe_env(self, arch=None, with_flags_in_cc=True):
19-
env = super(PILRecipe, self).get_recipe_env(arch, with_flags_in_cc)
13+
conflicts = ['pillow']
2014

21-
env['PYTHON_INCLUDE_ROOT'] = self.ctx.python_recipe.include_root(arch.arch)
22-
env['PYTHON_LINK_ROOT'] = self.ctx.python_recipe.link_root(arch.arch)
15+
def build_arch(self, arch):
16+
warning('PIL is no longer supported, building Pillow instead. '
17+
'This should be a drop-in replacement.')
18+
warning('It is recommended to change "pil" to "pillow" in your requirements, '
19+
'to ensure future compatibility')
20+
super(PilRecipe, self).build_arch(arch)
2321

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

27-
png = self.get_recipe('png', self.ctx)
28-
png_lib_dir = png.get_lib_dir(arch)
29-
png_jni_dir = png.get_jni_dir(arch)
30-
31-
jpeg = self.get_recipe('jpeg', self.ctx)
32-
jpeg_inc_dir = jpeg_lib_dir = jpeg.get_build_dir(arch.arch)
33-
34-
if 'freetype' in self.ctx.recipe_build_order:
35-
freetype = self.get_recipe('freetype', self.ctx)
36-
free_lib_dir = join(freetype.get_build_dir(arch.arch), 'objs', '.libs')
37-
free_inc_dir = join(freetype.get_build_dir(arch.arch), 'include')
38-
# hack freetype to be found by pil
39-
freetype_link = join(free_inc_dir, 'freetype')
40-
if not exists(freetype_link):
41-
shprint(sh.ln, '-s', join(free_inc_dir), freetype_link)
42-
43-
harfbuzz = self.get_recipe('harfbuzz', self.ctx)
44-
harf_lib_dir = join(harfbuzz.get_build_dir(arch.arch), 'src', '.libs')
45-
harf_inc_dir = harfbuzz.get_build_dir(arch.arch)
46-
47-
env['FREETYPE_ROOT'] = '{}|{}'.format(free_lib_dir, free_inc_dir)
48-
49-
env['JPEG_ROOT'] = '{}|{}'.format(jpeg_lib_dir, jpeg_inc_dir)
50-
env['ZLIB_ROOT'] = '{}|{}'.format(ndk_lib_dir, ndk_include_dir)
51-
52-
cflags = ' -std=c99'
53-
cflags += ' -I{}'.format(png_jni_dir)
54-
if 'freetype' in self.ctx.recipe_build_order:
55-
cflags += ' -I{} -I{}'.format(harf_inc_dir, join(harf_inc_dir, 'src'))
56-
cflags += ' -I{}'.format(free_inc_dir)
57-
cflags += ' -I{}'.format(jpeg_inc_dir)
58-
cflags += ' -I{}'.format(ndk_include_dir)
59-
60-
py_v = self.ctx.python_recipe.major_minor_version_string
61-
if py_v[0] == '3':
62-
py_v += 'm'
63-
64-
env['LIBS'] = ' -lpython{version} -lpng'.format(version=py_v)
65-
if 'freetype' in self.ctx.recipe_build_order:
66-
env['LIBS'] += ' -lfreetype -lharfbuzz'
67-
env['LIBS'] += ' -ljpeg -lturbojpeg'
68-
69-
env['LDFLAGS'] += ' -L{} -L{}'.format(env['PYTHON_LINK_ROOT'], png_lib_dir)
70-
if 'freetype' in self.ctx.recipe_build_order:
71-
env['LDFLAGS'] += ' -L{} -L{}'.format(harf_lib_dir, free_lib_dir)
72-
env['LDFLAGS'] += ' -L{} -L{}'.format(jpeg_lib_dir, ndk_lib_dir)
73-
74-
if cflags not in env['CFLAGS']:
75-
env['CFLAGS'] += cflags
76-
return env
77-
78-
79-
recipe = PILRecipe()
23+
recipe = PilRecipe()

pythonforandroid/recipes/pil/disable-tk.patch

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

pythonforandroid/recipes/pil/fix-directories.patch

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

0 commit comments

Comments
 (0)