Skip to content

Commit c1609f8

Browse files
committed
recipes: new pycairo recipe
1 parent 6f3ab80 commit c1609f8

File tree

6 files changed

+175
-2
lines changed

6 files changed

+175
-2
lines changed

pythonforandroid/recipe.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,6 +1290,7 @@ class MesonRecipe(PyProjectRecipe):
12901290

12911291
meson_version = "1.4.0"
12921292
ninja_version = "1.11.1.1"
1293+
no_python = False
12931294

12941295
def sanitize_flags(self, *flag_strings):
12951296
return " ".join(flag_strings).strip().split(" ")
@@ -1372,7 +1373,8 @@ def build_arch(self, arch):
13721373
]:
13731374
if dep not in self.hostpython_prerequisites:
13741375
self.hostpython_prerequisites.append(dep)
1375-
super().build_arch(arch)
1376+
if not self.no_python:
1377+
super().build_arch(arch)
13761378

13771379

13781380
class RustCompiledComponentsRecipe(PyProjectRecipe):
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from pythonforandroid.recipe import Recipe, MesonRecipe
2+
from os.path import join
3+
from pythonforandroid.util import ensure_dir, current_directory
4+
from pythonforandroid.logger import shprint
5+
from multiprocessing import cpu_count
6+
import sh
7+
8+
9+
class LibCairoRecipe(MesonRecipe):
10+
name = 'libcairo'
11+
version = '1.18.4'
12+
url = 'https://gitlab.freedesktop.org/cairo/cairo/-/archive/{version}/cairo-{version}.tar.bz2'
13+
no_python = True
14+
depends = ["png", "freetype"]
15+
patches = ["meson.patch"]
16+
built_libraries = {
17+
'libcairo.so': 'install/lib',
18+
'libpixman-1.so': 'install/lib',
19+
'libcairo-script-interpreter.so': 'install/lib'
20+
}
21+
22+
def should_build(self, arch):
23+
return Recipe.should_build(self, arch)
24+
25+
def build_arch(self, arch):
26+
super().build_arch(arch)
27+
build_dir = self.get_build_dir(arch.arch)
28+
install_dir = join(build_dir, 'install')
29+
ensure_dir(install_dir)
30+
env = self.get_recipe_env(arch)
31+
32+
lib_dir = self.ctx.get_libs_dir(arch.arch)
33+
png_include = self.get_recipe('png', self.ctx).get_build_dir(arch.arch)
34+
freetype_inc = join(self.get_recipe('freetype', self.ctx).get_build_dir(arch), "include")
35+
36+
with current_directory(build_dir):
37+
shprint(sh.meson, 'setup', 'builddir',
38+
'--cross-file', join("/tmp", "android.meson.cross"),
39+
f'--prefix={install_dir}',
40+
'-Dpng=enabled',
41+
'-Dzlib=enabled',
42+
'-Dglib=disabled',
43+
'-Dgtk_doc=false',
44+
'-Dsymbol-lookup=disabled',
45+
46+
# deps
47+
f'-Dpng_include_dir={png_include}',
48+
f'-Dpng_lib_dir={lib_dir}',
49+
f'-Dfreetype_include_dir={freetype_inc}',
50+
f'-Dfreetype_lib_dir={lib_dir}',
51+
_env=env)
52+
53+
shprint(sh.ninja, '-C', 'builddir', '-j', str(cpu_count()), _env=env)
54+
shprint(sh.ninja, '-C', 'builddir', 'install', _env=env)
55+
56+
57+
recipe = LibCairoRecipe()
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
diff '--color=auto' -uNr cairo-1.18.4/meson.build cairo-1.18.4.mod/meson.build
2+
--- cairo-1.18.4/meson.build 2025-03-08 18:53:25.000000000 +0530
3+
+++ cairo-1.18.4.mod/meson.build 2025-07-14 20:42:56.226164648 +0530
4+
@@ -235,11 +235,13 @@
5+
conf.set('HAVE_ZLIB', 1)
6+
endif
7+
8+
-png_dep = dependency('libpng',
9+
- required: get_option('png'),
10+
- version: libpng_required_version,
11+
- fallback: ['libpng', 'libpng_dep']
12+
+png_inc = include_directories(get_option('png_include_dir'))
13+
+png_lib = cc.find_library('png16', dirs: [get_option('png_lib_dir')], required: true)
14+
+png_dep = declare_dependency(
15+
+ include_directories: png_inc,
16+
+ dependencies: [png_lib]
17+
)
18+
+
19+
if png_dep.found()
20+
feature_conf.set('CAIRO_HAS_SVG_SURFACE', 1)
21+
feature_conf.set('CAIRO_HAS_PNG_FUNCTIONS', 1)
22+
@@ -265,7 +267,7 @@
23+
24+
# Disable fontconfig by default on platforms where it is optional
25+
fontconfig_option = get_option('fontconfig')
26+
-fontconfig_required = host_machine.system() not in ['windows', 'darwin']
27+
+fontconfig_required = false
28+
fontconfig_option = fontconfig_option.disable_auto_if(not fontconfig_required)
29+
30+
fontconfig_dep = dependency('fontconfig',
31+
@@ -304,11 +306,14 @@
32+
freetype_required = host_machine.system() not in ['windows', 'darwin']
33+
freetype_option = freetype_option.disable_auto_if(not freetype_required)
34+
35+
-freetype_dep = dependency('freetype2',
36+
- required: freetype_option,
37+
- version: freetype_required_version,
38+
- fallback: ['freetype2', 'freetype_dep'],
39+
+freetype_inc = include_directories(get_option('freetype_include_dir'))
40+
+freetype_lib = cc.find_library('freetype', dirs: [get_option('freetype_lib_dir')], required: true)
41+
+
42+
+freetype_dep = declare_dependency(
43+
+ include_directories: freetype_inc,
44+
+ dependencies: [freetype_lib]
45+
)
46+
+
47+
if freetype_dep.found()
48+
feature_conf.set('CAIRO_HAS_FT_FONT', 1)
49+
built_features += [{
50+
diff '--color=auto' -uNr cairo-1.18.4/meson.options cairo-1.18.4.mod/meson.options
51+
--- cairo-1.18.4/meson.options 2025-03-08 18:53:25.000000000 +0530
52+
+++ cairo-1.18.4.mod/meson.options 2025-07-14 20:43:00.473191452 +0530
53+
@@ -28,3 +28,11 @@
54+
# Documentation
55+
option('gtk_doc', type : 'boolean', value : false,
56+
description: 'Build the Cairo API reference (depends on gtk-doc)')
57+
+
58+
+# Deps
59+
+
60+
+option('png_include_dir', type: 'string', value: '', description: 'Path to PNG headers')
61+
+option('png_lib_dir', type: 'string', value: '', description: 'Path to PNG library')
62+
+option('freetype_include_dir', type: 'string', value: '', description: 'Path to FreeType headers')
63+
+option('freetype_lib_dir', type: 'string', value: '', description: 'Path to FreeType library')
64+
+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from pythonforandroid.recipe import MesonRecipe
2+
from os.path import join
3+
4+
5+
class PyCairoRecipe(MesonRecipe):
6+
version = '1.28.0'
7+
url = 'https://github.com/pygobject/pycairo/releases/download/v{version}/pycairo-{version}.tar.gz'
8+
name = 'pycairo'
9+
site_packages_name = 'cairo'
10+
depends = ['libcairo']
11+
patches = ["meson.patch"]
12+
13+
def build_arch(self, arch):
14+
15+
include_path = join(self.get_recipe('libcairo', self.ctx).get_build_dir(arch), "install", "include", "cairo")
16+
lib_path = self.ctx.get_libs_dir(arch.arch)
17+
18+
self.extra_build_args += [
19+
f'-Csetup-args=-Dcairo_include={include_path}',
20+
f'-Csetup-args=-Dcairo_lib={lib_path}',
21+
]
22+
23+
super().build_arch(arch)
24+
25+
26+
recipe = PyCairoRecipe()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
diff '--color=auto' -uNr pycairo-1.28.0/cairo/meson.build pycairo-1.28.0.mod/cairo/meson.build
2+
--- pycairo-1.28.0/cairo/meson.build 2025-04-15 00:22:30.000000000 +0530
3+
+++ pycairo-1.28.0.mod/cairo/meson.build 2025-07-14 21:56:34.782983845 +0530
4+
@@ -28,7 +28,10 @@
5+
fs.copyfile(python_file, python_file)
6+
endforeach
7+
8+
-cairo_dep = dependency('cairo', version: cair_version_req, required: cc.get_id() != 'msvc')
9+
+cairo_dep = declare_dependency(
10+
+ include_directories: include_directories(get_option('cairo_include')),
11+
+ link_args: ['-L' + get_option('cairo_lib'), '-lcairo']
12+
+)
13+
14+
if cc.get_id() == 'msvc' and not cairo_dep.found()
15+
if cc.has_header('cairo.h')
16+
diff '--color=auto' -uNr pycairo-1.28.0/meson_options.txt pycairo-1.28.0.mod/meson_options.txt
17+
--- pycairo-1.28.0/meson_options.txt 2025-04-15 00:22:30.000000000 +0530
18+
+++ pycairo-1.28.0.mod/meson_options.txt 2025-07-14 21:56:52.824191314 +0530
19+
@@ -1,3 +1,5 @@
20+
option('python', type : 'string', value : 'python3')
21+
option('tests', type : 'boolean', value : true, description : 'build unit tests')
22+
option('wheel', type : 'boolean', value : false, description : 'build for a Python wheel')
23+
+option('cairo_include', type: 'string', value: '', description: 'Path to cairo headers')
24+
+option('cairo_lib', type: 'string', value: '', description: 'Path to cairo libraries')

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
# https://github.com/kivy/buildozer/issues/722
2222
install_reqs = [
2323
'appdirs', 'colorama>=0.3.3', 'jinja2',
24-
'sh>=2, <3.0; sys_platform!="win32"',
24+
'sh>=2, <3.0; sys_platform!="win32"', 'meson',
2525
'build', 'toml', 'packaging', 'setuptools', 'wheel~=0.43.0'
2626
]
2727
# (build and toml are used by pythonpackage.py)

0 commit comments

Comments
 (0)