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

kivy / python-for-android / 26682386815

30 May 2026 11:14AM UTC coverage: 62.67% (-1.2%) from 63.887%
26682386815

Pull #3278

github

web-flow
Merge 77aee3d95 into 74b559a3c
Pull Request #3278: Handling system bars and Edge-to-Edge enforcement (android 15+)

1832 of 3194 branches covered (57.36%)

Branch coverage included in aggregate %.

5407 of 8357 relevant lines covered (64.7%)

3.88 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
6✔
2
from os.path import join, exists
6✔
3
from pythonforandroid.util import ensure_dir, current_directory
6✔
4
from pythonforandroid.logger import shprint
6✔
5
from multiprocessing import cpu_count
6✔
6
import sh
6✔
7

8

9
class LibCairoRecipe(MesonRecipe):
6✔
10
    name = 'libcairo'
6✔
11
    version = '1.18.4'
6✔
12
    url = 'https://gitlab.freedesktop.org/cairo/cairo/-/archive/{version}/cairo-{version}.tar.bz2'
6✔
13
    skip_python = True
6✔
14
    depends = ["png", "freetype"]
6✔
15
    patches = ["meson.patch"]
6✔
16
    built_libraries = {
6✔
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):
6✔
23
        env = super().get_recipe_env(arch, **kwargs)
×
24
        cpufeatures = join(self.ctx.ndk.ndk_dir, "sources/android/cpufeatures")
×
25
        lib_dir = join(cpufeatures, "obj", "local", arch.arch)
×
26
        env["CFLAGS"] += f" -I{cpufeatures}"
×
27
        env["LDFLAGS"] += f" -L{lib_dir} -lcpufeatures"
×
28
        return env
×
29

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

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

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

44
        with current_directory(build_dir):
×
45

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

49
            if not exists(lib_file):
×
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

59
            shprint(self.get_meson_command(env), '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

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

86
            shprint(
×
87
                self.get_ninja_command(env),
88
                '-C', 'builddir', 'install',
89
                _env=env
90
            )
91

92

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

© 2026 Coveralls, Inc