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

kivy / python-for-android / 17517234198

06 Sep 2025 05:07PM UTC coverage: 58.947% (-0.3%) from 59.214%
17517234198

Pull #3202

github

web-flow
Merge 11300622b into 5330267b5
Pull Request #3202: [WIP] Add Skia recipe for Kivy 3.0.0.dev0

1060 of 2403 branches covered (44.11%)

Branch coverage included in aggregate %.

23 of 65 new or added lines in 2 files covered. (35.38%)

4985 of 7852 relevant lines covered (63.49%)

2.53 hits per line

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

25.64
/pythonforandroid/recipes/skia/__init__.py
1
import sys
4✔
2
import os
4✔
3
import shutil
4✔
4
from os.path import join, exists, basename
4✔
5
import sh
4✔
6
from pythonforandroid.recipe import Recipe
4✔
7
from pythonforandroid.toolchain import shprint, current_directory
4✔
8
from pythonforandroid.util import ensure_dir
4✔
9

10

11
class SkiaRecipe(Recipe):
4✔
12
    version = "skia-binaries-m140-rev1.a0"
4✔
13
    url = "https://github.com/DexerBR/skia-builder/releases/download/{version}/android-merged.tar.gz"
4✔
14
    name = "skia"
4✔
15

16
    skia_libraries = [
4✔
17
        "libskparagraph.a",
18
        "libskia.a",
19
        "libskottie.a",
20
        "libsksg.a",
21
        "libskshaper.a",
22
        "libskunicode_icu.a",
23
        "libskunicode_core.a",
24
        "libjsonreader.a",
25
    ]
26

27
    built_libraries = {"libskmerged.a": "bin"}
4✔
28

29
    def _get_skia_platform(self, arch):
4✔
NEW
30
        arch_map = {
×
31
            "arm64-v8a": "android-arm64",
32
            "armeabi-v7a": "android-arm",
33
            "x86_64": "android-x64",
34
            "x86": "android-x86",
35
        }
NEW
36
        arch_name = arch.arch if hasattr(arch, "arch") else arch
×
NEW
37
        return arch_map.get(arch_name, arch_name)
×
38

39
    def unpack(self, arch):
4✔
NEW
40
        build_dir = self.get_build_container_dir(arch)
×
NEW
41
        target_dir = self.get_build_dir(arch)
×
42

NEW
43
        if exists(target_dir):
×
NEW
44
            return
×
45

NEW
46
        ensure_dir(build_dir)
×
47

NEW
48
        filename = basename(self.versioned_url)
×
NEW
49
        archive_path = join(self.ctx.packages_path, self.name, filename)
×
NEW
50
        skia_platform = self._get_skia_platform(arch)
×
51

NEW
52
        with current_directory(build_dir):
×
NEW
53
            temp_extract_dir = join(build_dir, "temp_extract")
×
NEW
54
            ensure_dir(temp_extract_dir)
×
55

NEW
56
            with current_directory(temp_extract_dir):
×
NEW
57
                shprint(sh.tar, "xzf", archive_path)
×
58

NEW
59
            ensure_dir(target_dir)
×
60

61
            # Find and extract the architecture-specific tar.gz
NEW
62
            arch_file = f"{skia_platform}.tar.gz"
×
NEW
63
            arch_file_path = join(temp_extract_dir, arch_file)
×
64

NEW
65
            if exists(arch_file_path):
×
NEW
66
                print(f"Found {arch_file}, extracting...")
×
NEW
67
                with current_directory(target_dir):
×
NEW
68
                    shprint(sh.tar, "xzf", arch_file_path)
×
69
            else:
NEW
70
                print(f"Architecture file not found: {arch_file}")
×
NEW
71
                print(f"Available files: {os.listdir(temp_extract_dir)}")
×
NEW
72
                sys.exit(1)
×
73

NEW
74
            shutil.rmtree(temp_extract_dir)
×
75

76
    def build_arch(self, arch):
4✔
NEW
77
        build_dir = self.get_build_dir(arch.arch)
×
NEW
78
        merged_lib_path = join(build_dir, "bin", "libskmerged.a")
×
79

NEW
80
        lib_files = []
×
NEW
81
        for lib in self.skia_libraries:
×
NEW
82
            lib_path = join(build_dir, "bin", lib)
×
NEW
83
            if exists(lib_path):
×
NEW
84
                lib_files.append(lib_path)
×
85

NEW
86
        if lib_files:
×
NEW
87
            with current_directory(build_dir):
×
NEW
88
                shprint(
×
89
                    sh.Command(self.ctx.ndk.llvm_ar),
90
                    "rcs",
91
                    merged_lib_path,
92
                    *lib_files,
93
                )
94

95
    def get_include_dirs(self, arch):
4✔
NEW
96
        build_dir = self.get_build_dir(arch.arch)
×
NEW
97
        return [
×
98
            d
99
            for d in [
100
                join(build_dir, subdir)
101
                for subdir in ["include", "modules", "src"]
102
            ]
103
            if exists(d)
104
        ]
105

106
    def get_lib_dir(self, arch):
4✔
NEW
107
        return self.get_build_dir(arch.arch)
×
108

109

110
recipe = SkiaRecipe()
4✔
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

© 2025 Coveralls, Inc