• 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

36.92
/pythonforandroid/recipes/kivy/__init__.py
1
from os.path import join
6✔
2
import sys
6✔
3
import packaging.version
6✔
4

5
import sh
6✔
6
from pythonforandroid.recipe import PyProjectRecipe, Recipe
6✔
7
from pythonforandroid.toolchain import current_directory, shprint
6✔
8

9

10
def get_kivy_version(recipe, arch):
6✔
11
    with current_directory(join(recipe.get_build_dir(arch.arch), "kivy")):
×
12
        return shprint(
×
13
            sh.Command(sys.executable),
14
            "-c",
15
            "import _version; print(_version.__version__)",
16
        )
17

18

19
def is_kivy_affected_by_deadlock_issue(recipe=None, arch=None):
6✔
20
    return packaging.version.parse(
×
21
        str(get_kivy_version(recipe, arch))
22
    ) < packaging.version.Version("2.2.0.dev0")
23

24

25
def is_kivy_less_than_3(recipe=None, arch=None):
6✔
26
    return packaging.version.parse(
×
27
        str(get_kivy_version(recipe, arch))
28
    ) < packaging.version.Version("3.0.0.dev0")
29

30

31
class KivyRecipe(PyProjectRecipe):
6✔
32
    version = '2.3.1'
6✔
33
    url = 'https://github.com/kivy/kivy/archive/{version}.zip'
6✔
34
    name = 'kivy'
6✔
35

36
    depends = [('sdl2', 'sdl3'), 'pyjnius', 'setuptools', 'android', 'libthorvg']
6✔
37
    python_depends = ['certifi', 'chardet', 'idna', 'requests', 'urllib3', 'filetype']
6✔
38
    hostpython_prerequisites = ["cython>=0.29.1,<=3.0.12"]
6✔
39

40
    # sdl-gl-swapwindow-nogil.patch is needed to avoid a deadlock.
41
    # See: https://github.com/kivy/kivy/pull/8025
42
    # WARNING: Remove this patch when a new Kivy version is released.
43
    patches = [
6✔
44
        ("sdl-gl-swapwindow-nogil.patch", is_kivy_affected_by_deadlock_issue),
45
        ("use_cython.patch", is_kivy_less_than_3),
46
        "no-ast-str.patch"
47
    ]
48

49
    @property
6✔
50
    def need_stl_shared(self):
6✔
51
        if "sdl3" in self.ctx.recipe_build_order:
×
52
            return True
×
53
        else:
54
            return False
×
55

56
    def get_recipe_env(self, arch, **kwargs):
6✔
57
        env = super().get_recipe_env(arch, **kwargs)
×
58

59
        # Taken from CythonRecipe
60
        env['LDFLAGS'] = env['LDFLAGS'] + ' -L{} '.format(
×
61
            self.ctx.get_libs_dir(arch.arch) +
62
            ' -L{} '.format(self.ctx.libs_dir) +
63
            ' -L{}'.format(join(self.ctx.bootstrap.build_dir, 'obj', 'local',
64
                                arch.arch)))
65
        env['LDSHARED'] = env['CC'] + ' -shared'
×
66
        env['LIBLINK'] = 'NOTNONE'
×
67

68
        # NDKPLATFORM is our switch for detecting Android platform, so can't be None
69
        env['NDKPLATFORM'] = "NOTNONE"
×
70
        if not is_kivy_less_than_3(self, arch):
×
71
            env['KIVY_CROSS_PLATFORM'] = 'android'
×
72

73
        # thorvg headers
74
        env['KIVY_THORVG_LIB_DIR'] = self.ctx.get_libs_dir(arch.arch)
×
75
        env['KIVY_THORVG_INCLUDE_DIR'] = join(
×
76
            Recipe.get_recipe('libthorvg', self.ctx).get_include_dir(arch),
77
            'thorvg-1'
78
        )
79

80
        if 'sdl2' in self.ctx.recipe_build_order:
×
81
            env['USE_SDL2'] = '1'
×
82
            env['KIVY_SPLIT_EXAMPLES'] = '1'
×
83
            sdl2_mixer_recipe = self.get_recipe('sdl2_mixer', self.ctx)
×
84
            sdl2_image_recipe = self.get_recipe('sdl2_image', self.ctx)
×
85
            env['KIVY_SDL2_PATH'] = ':'.join([
×
86
                join(self.ctx.bootstrap.build_dir, 'jni', 'SDL', 'include'),
87
                *sdl2_image_recipe.get_include_dirs(arch),
88
                *sdl2_mixer_recipe.get_include_dirs(arch),
89
                join(self.ctx.bootstrap.build_dir, 'jni', 'SDL2_ttf'),
90
            ])
91
        if "sdl3" in self.ctx.recipe_build_order:
×
92
            sdl3_mixer_recipe = self.get_recipe("sdl3_mixer", self.ctx)
×
93
            sdl3_image_recipe = self.get_recipe("sdl3_image", self.ctx)
×
94
            sdl3_ttf_recipe = self.get_recipe("sdl3_ttf", self.ctx)
×
95
            sdl3_recipe = self.get_recipe("sdl3", self.ctx)
×
96
            env["USE_SDL3"] = "1"
×
97
            env["KIVY_SPLIT_EXAMPLES"] = "1"
×
98
            env["KIVY_SDL3_PATH"] = ":".join(
×
99
                [
100
                    *sdl3_mixer_recipe.get_include_dirs(arch),
101
                    *sdl3_image_recipe.get_include_dirs(arch),
102
                    *sdl3_ttf_recipe.get_include_dirs(arch),
103
                    *sdl3_recipe.get_include_dirs(arch),
104
                ]
105
            )
106

107
        return env
×
108

109

110
recipe = KivyRecipe()
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