• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kivy / python-for-android / 18449661967

12 Oct 2025 09:20PM UTC coverage: 59.033% (-0.08%) from 59.116%
18449661967

push

github

web-flow
Merge pull request #3174 from T-Dynamos/develop

`recipes`: new pycairo recipe

1071 of 2417 branches covered (44.31%)

Branch coverage included in aggregate %.

31 of 62 new or added lines in 3 files covered. (50.0%)

5020 of 7901 relevant lines covered (63.54%)

5.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

38.3
/pythonforandroid/recipes/libcairo/__init__.py
1
from pythonforandroid.recipe import Recipe, MesonRecipe
8✔
2
from os.path import join, exists
8✔
3
from pythonforandroid.util import ensure_dir, current_directory
8✔
4
from pythonforandroid.logger import shprint
8✔
5
from multiprocessing import cpu_count
8✔
6
import sh
8✔
7

8

9
class LibCairoRecipe(MesonRecipe):
8✔
10
    name = 'libcairo'
8✔
11
    version = '1.18.4'
8✔
12
    url = 'https://gitlab.freedesktop.org/cairo/cairo/-/archive/{version}/cairo-{version}.tar.bz2'
8✔
13
    skip_python = True
8✔
14
    depends = ["png", "freetype"]
8✔
15
    patches = ["meson.patch"]
8✔
16
    built_libraries = {
8✔
17
        'libcairo.so': 'install/lib',
18
        'libpixman-1.so': 'install/lib',
19
        'libcairo-script-interpreter.so': 'install/lib'
20
    }
21

22
    def get_recipe_env(self, arch, **kwargs):
8✔
NEW
23
        env = super().get_recipe_env(arch, **kwargs)
×
NEW
24
        cpufeatures = join(self.ctx.ndk.ndk_dir, "sources/android/cpufeatures")
×
NEW
25
        lib_dir = join(cpufeatures, "obj", "local", arch.arch)
×
NEW
26
        env["CFLAGS"] += f" -I{cpufeatures}"
×
NEW
27
        env["LDFLAGS"] += f" -L{lib_dir} -lcpufeatures"
×
NEW
28
        return env
×
29

30
    def should_build(self, arch):
8✔
NEW
31
        return Recipe.should_build(self, arch)
×
32

33
    def build_arch(self, arch):
8✔
NEW
34
        super().build_arch(arch)
×
NEW
35
        build_dir = self.get_build_dir(arch.arch)
×
NEW
36
        install_dir = join(build_dir, 'install')
×
NEW
37
        ensure_dir(install_dir)
×
NEW
38
        env = self.get_recipe_env(arch)
×
39

NEW
40
        lib_dir = self.ctx.get_libs_dir(arch.arch)
×
NEW
41
        png_include = self.get_recipe('png', self.ctx).get_build_dir(arch.arch)
×
NEW
42
        freetype_inc = join(self.get_recipe('freetype', self.ctx).get_build_dir(arch), "include")
×
43

NEW
44
        with current_directory(build_dir):
×
45

NEW
46
            cpufeatures_dir = join(self.ctx.ndk.ndk_dir, "sources/android/cpufeatures")
×
NEW
47
            lib_file = join(cpufeatures_dir, "obj", "local", arch.arch, "libcpufeatures.a")
×
48

NEW
49
            if not exists(lib_file):
×
NEW
50
                shprint(
×
51
                    sh.Command(join(self.ctx.ndk_dir, "ndk-build")),
52
                    f"NDK_PROJECT_PATH={cpufeatures_dir}",
53
                    f"APP_BUILD_SCRIPT={cpufeatures_dir}/Android.mk",
54
                    f"APP_ABI={arch.arch}",
55
                    "APP_PLATFORM=latest",
56
                    _env=env
57
                )
58

NEW
59
            shprint(sh.meson, 'setup', 'builddir',
×
60
                    '--cross-file', join("/tmp", "android.meson.cross"),
61
                    f'--prefix={install_dir}',
62
                    '-Dpng=enabled',
63
                    '-Dzlib=enabled',
64
                    '-Dglib=disabled',
65
                    '-Dgtk_doc=false',
66
                    '-Dsymbol-lookup=disabled',
67

68
                    # deps
69
                    f'-Dpng_include_dir={png_include}',
70
                    f'-Dpng_lib_dir={lib_dir}',
71
                    f'-Dfreetype_include_dir={freetype_inc}',
72
                    f'-Dfreetype_lib_dir={lib_dir}',
73
                    _env=env)
74

NEW
75
            shprint(sh.ninja, '-C', 'builddir', '-j', str(cpu_count()), _env=env)
×
76
            # macOS fix: sometimes Ninja creates a dummy 'lib' file instead of a directory.
77
            # So we remove and recreate the install directory using shell commands,
78
            # since os.remove/os.makedirs behave inconsistently in this build env.
NEW
79
            shprint(sh.rm, '-rf', install_dir)
×
NEW
80
            shprint(sh.mkdir, install_dir)
×
81

NEW
82
            shprint(sh.ninja, '-C', 'builddir', 'install', _env=env)
×
83

84

85
recipe = LibCairoRecipe()
8✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc