Skip to content

recipes: new pycairo recipe #3174

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

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
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
4 changes: 3 additions & 1 deletion pythonforandroid/recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -1290,6 +1290,7 @@ class MesonRecipe(PyProjectRecipe):

meson_version = "1.4.0"
ninja_version = "1.11.1.1"
skip_python = False

def sanitize_flags(self, *flag_strings):
return " ".join(flag_strings).strip().split(" ")
Expand Down Expand Up @@ -1372,7 +1373,8 @@ def build_arch(self, arch):
]:
if dep not in self.hostpython_prerequisites:
self.hostpython_prerequisites.append(dep)
super().build_arch(arch)
if not self.skip_python:
super().build_arch(arch)


class RustCompiledComponentsRecipe(PyProjectRecipe):
Expand Down
57 changes: 57 additions & 0 deletions pythonforandroid/recipes/libcairo/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from pythonforandroid.recipe import Recipe, MesonRecipe
from os.path import join
from pythonforandroid.util import ensure_dir, current_directory
from pythonforandroid.logger import shprint
from multiprocessing import cpu_count
import sh


class LibCairoRecipe(MesonRecipe):
name = 'libcairo'
version = '1.18.4'
url = 'https://gitlab.freedesktop.org/cairo/cairo/-/archive/{version}/cairo-{version}.tar.bz2'
skip_python = True
depends = ["png", "freetype"]
patches = ["meson.patch"]
built_libraries = {
'libcairo.so': 'install/lib',
'libpixman-1.so': 'install/lib',
'libcairo-script-interpreter.so': 'install/lib'
}

def should_build(self, arch):
return Recipe.should_build(self, arch)

def build_arch(self, arch):
super().build_arch(arch)
build_dir = self.get_build_dir(arch.arch)
install_dir = join(build_dir, 'install')
ensure_dir(install_dir)
env = self.get_recipe_env(arch)

lib_dir = self.ctx.get_libs_dir(arch.arch)
png_include = self.get_recipe('png', self.ctx).get_build_dir(arch.arch)
freetype_inc = join(self.get_recipe('freetype', self.ctx).get_build_dir(arch), "include")

with current_directory(build_dir):
shprint(sh.meson, 'setup', 'builddir',
'--cross-file', join("/tmp", "android.meson.cross"),
f'--prefix={install_dir}',
'-Dpng=enabled',
'-Dzlib=enabled',
'-Dglib=disabled',
'-Dgtk_doc=false',
'-Dsymbol-lookup=disabled',

# deps
f'-Dpng_include_dir={png_include}',
f'-Dpng_lib_dir={lib_dir}',
f'-Dfreetype_include_dir={freetype_inc}',
f'-Dfreetype_lib_dir={lib_dir}',
_env=env)

shprint(sh.ninja, '-C', 'builddir', '-j', str(cpu_count()), _env=env)
shprint(sh.ninja, '-C', 'builddir', 'install', _env=env)


recipe = LibCairoRecipe()
64 changes: 64 additions & 0 deletions pythonforandroid/recipes/libcairo/meson.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
diff '--color=auto' -uNr cairo-1.18.4/meson.build cairo-1.18.4.mod/meson.build
--- cairo-1.18.4/meson.build 2025-03-08 18:53:25.000000000 +0530
+++ cairo-1.18.4.mod/meson.build 2025-07-14 20:42:56.226164648 +0530
@@ -235,11 +235,13 @@
conf.set('HAVE_ZLIB', 1)
endif

-png_dep = dependency('libpng',
- required: get_option('png'),
- version: libpng_required_version,
- fallback: ['libpng', 'libpng_dep']
+png_inc = include_directories(get_option('png_include_dir'))
+png_lib = cc.find_library('png16', dirs: [get_option('png_lib_dir')], required: true)
+png_dep = declare_dependency(
+ include_directories: png_inc,
+ dependencies: [png_lib]
)
+
if png_dep.found()
feature_conf.set('CAIRO_HAS_SVG_SURFACE', 1)
feature_conf.set('CAIRO_HAS_PNG_FUNCTIONS', 1)
@@ -265,7 +267,7 @@

# Disable fontconfig by default on platforms where it is optional
fontconfig_option = get_option('fontconfig')
-fontconfig_required = host_machine.system() not in ['windows', 'darwin']
+fontconfig_required = false
fontconfig_option = fontconfig_option.disable_auto_if(not fontconfig_required)

fontconfig_dep = dependency('fontconfig',
@@ -304,11 +306,14 @@
freetype_required = host_machine.system() not in ['windows', 'darwin']
freetype_option = freetype_option.disable_auto_if(not freetype_required)

-freetype_dep = dependency('freetype2',
- required: freetype_option,
- version: freetype_required_version,
- fallback: ['freetype2', 'freetype_dep'],
+freetype_inc = include_directories(get_option('freetype_include_dir'))
+freetype_lib = cc.find_library('freetype', dirs: [get_option('freetype_lib_dir')], required: true)
+
+freetype_dep = declare_dependency(
+ include_directories: freetype_inc,
+ dependencies: [freetype_lib]
)
+
if freetype_dep.found()
feature_conf.set('CAIRO_HAS_FT_FONT', 1)
built_features += [{
diff '--color=auto' -uNr cairo-1.18.4/meson.options cairo-1.18.4.mod/meson.options
--- cairo-1.18.4/meson.options 2025-03-08 18:53:25.000000000 +0530
+++ cairo-1.18.4.mod/meson.options 2025-07-14 20:43:00.473191452 +0530
@@ -28,3 +28,11 @@
# Documentation
option('gtk_doc', type : 'boolean', value : false,
description: 'Build the Cairo API reference (depends on gtk-doc)')
+
+# Deps
+
+option('png_include_dir', type: 'string', value: '', description: 'Path to PNG headers')
+option('png_lib_dir', type: 'string', value: '', description: 'Path to PNG library')
+option('freetype_include_dir', type: 'string', value: '', description: 'Path to FreeType headers')
+option('freetype_lib_dir', type: 'string', value: '', description: 'Path to FreeType library')
+
26 changes: 26 additions & 0 deletions pythonforandroid/recipes/pycairo/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from pythonforandroid.recipe import MesonRecipe
from os.path import join


class PyCairoRecipe(MesonRecipe):
version = '1.28.0'
url = 'https://github.com/pygobject/pycairo/releases/download/v{version}/pycairo-{version}.tar.gz'
name = 'pycairo'
site_packages_name = 'cairo'
depends = ['libcairo']
patches = ["meson.patch"]

def build_arch(self, arch):

include_path = join(self.get_recipe('libcairo', self.ctx).get_build_dir(arch), "install", "include", "cairo")
lib_path = self.ctx.get_libs_dir(arch.arch)

self.extra_build_args += [
f'-Csetup-args=-Dcairo_include={include_path}',
f'-Csetup-args=-Dcairo_lib={lib_path}',
]

super().build_arch(arch)


recipe = PyCairoRecipe()
24 changes: 24 additions & 0 deletions pythonforandroid/recipes/pycairo/meson.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
diff '--color=auto' -uNr pycairo-1.28.0/cairo/meson.build pycairo-1.28.0.mod/cairo/meson.build
--- pycairo-1.28.0/cairo/meson.build 2025-04-15 00:22:30.000000000 +0530
+++ pycairo-1.28.0.mod/cairo/meson.build 2025-07-14 21:56:34.782983845 +0530
@@ -28,7 +28,10 @@
fs.copyfile(python_file, python_file)
endforeach

-cairo_dep = dependency('cairo', version: cair_version_req, required: cc.get_id() != 'msvc')
+cairo_dep = declare_dependency(
+ include_directories: include_directories(get_option('cairo_include')),
+ link_args: ['-L' + get_option('cairo_lib'), '-lcairo']
+)

if cc.get_id() == 'msvc' and not cairo_dep.found()
if cc.has_header('cairo.h')
diff '--color=auto' -uNr pycairo-1.28.0/meson_options.txt pycairo-1.28.0.mod/meson_options.txt
--- pycairo-1.28.0/meson_options.txt 2025-04-15 00:22:30.000000000 +0530
+++ pycairo-1.28.0.mod/meson_options.txt 2025-07-14 21:56:52.824191314 +0530
@@ -1,3 +1,5 @@
option('python', type : 'string', value : 'python3')
option('tests', type : 'boolean', value : true, description : 'build unit tests')
option('wheel', type : 'boolean', value : false, description : 'build for a Python wheel')
+option('cairo_include', type: 'string', value: '', description: 'Path to cairo headers')
+option('cairo_lib', type: 'string', value: '', description: 'Path to cairo libraries')
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
# https://github.com/kivy/buildozer/issues/722
install_reqs = [
'appdirs', 'colorama>=0.3.3', 'jinja2',
'sh>=2, <3.0; sys_platform!="win32"',
'sh>=2, <3.0; sys_platform!="win32"', 'meson', 'ninja',
'build', 'toml', 'packaging', 'setuptools', 'wheel~=0.43.0'
]
# (build and toml are used by pythonpackage.py)
Expand Down
Loading