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

kivy / python-for-android / 22259302242

21 Feb 2026 03:24PM UTC coverage: 63.887% (+4.7%) from 59.214%
22259302242

Pull #3198

github

web-flow
Merge 758a52847 into 1fc026943
Pull Request #3198: Bump SDL3 (`3.4.2`) and SDL3_image (`3.4.0`) to the latest stable releases.

1823 of 3111 branches covered (58.6%)

Branch coverage included in aggregate %.

3 of 3 new or added lines in 2 files covered. (100.0%)

788 existing lines in 24 files now uncovered.

5287 of 8018 relevant lines covered (65.94%)

5.26 hits per line

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

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

8

9
class FreetypeRecipe(Recipe):
8✔
10
    """The freetype library it's special, because has cyclic dependencies with
11
    harfbuzz library, so freetype can be build with harfbuzz support, and
12
    harfbuzz can be build with freetype support. This complicates the build of
13
    both recipes because in order to get the full set we need to compile those
14
    recipes several times:
15
        - build freetype without harfbuzz
16
        - build harfbuzz with freetype
17
        - build freetype with harfbuzz support
18

19
    .. note::
20
        To build freetype with harfbuzz support you must add `harfbuzz` to your
21
        requirements, otherwise freetype will be build without harfbuzz
22

23
    .. seealso::
24
        https://sourceforge.net/projects/freetype/files/freetype2/2.5.3/
25
    """
26

27
    version = '2.14.1'
8✔
28
    url = 'https://download.savannah.gnu.org/releases/freetype/freetype-{version}.tar.gz'  # noqa
8✔
29
    built_libraries = {'libfreetype.so': 'objs/.libs'}
8✔
30

31
    def get_recipe_env(self, arch=None, with_harfbuzz=False):
8✔
32
        env = super().get_recipe_env(arch)
8✔
33
        if with_harfbuzz:
8!
34
            harfbuzz_build = self.get_recipe(
×
35
                'harfbuzz', self.ctx
36
            ).get_build_dir(arch.arch)
37
            freetype_install = join(self.get_build_dir(arch.arch), 'install')
×
38

39
            env['HARFBUZZ_CFLAGS'] = '-I{harfbuzz} -I{harfbuzz}/src'.format(
×
40
                harfbuzz=harfbuzz_build
41
            )
42
            env['HARFBUZZ_LIBS'] = (
×
43
                '-L{freetype}/lib -lfreetype '
44
                '-L{harfbuzz}/src/.libs -lharfbuzz'.format(
45
                    freetype=freetype_install, harfbuzz=harfbuzz_build
46
                )
47
            )
48

49
        # android's zlib support
50
        zlib_lib_path = arch.ndk_lib_dir_versioned
8✔
51
        zlib_includes = self.ctx.ndk.sysroot_include_dir
8✔
52

53
        def add_flag_if_not_added(flag, env_key):
8✔
54
            if flag not in env[env_key]:
8!
55
                env[env_key] += flag
8✔
56

57
        add_flag_if_not_added(' -I' + zlib_includes, 'CFLAGS')
8✔
58
        add_flag_if_not_added(' -L' + zlib_lib_path, 'LDFLAGS')
8✔
59
        add_flag_if_not_added(' -lz', 'LDLIBS')
8✔
60

61
        return env
8✔
62

63
    def build_arch(self, arch, with_harfbuzz=False):
8✔
64
        env = self.get_recipe_env(arch, with_harfbuzz=with_harfbuzz)
8✔
65

66
        harfbuzz_in_recipes = 'harfbuzz' in self.ctx.recipe_build_order
8✔
67
        prefix_path = self.get_build_dir(arch.arch)
8✔
68
        if harfbuzz_in_recipes and not with_harfbuzz:
8!
69
            # This is the first time we build freetype and we modify `prefix`,
70
            # because we will install the compiled library so later we can
71
            # build harfbuzz (with freetype support) using this freetype
72
            # installation
73
            prefix_path = join(prefix_path, 'install')
×
74

75
        # Configure freetype library
76
        config_args = {
8✔
77
            '--host={}'.format(arch.command_prefix),
78
            '--prefix={}'.format(prefix_path),
79
            '--without-bzip2',
80
            '--without-brotli',
81
            '--with-png=no',
82
        }
83
        if not harfbuzz_in_recipes:
8!
84
            info('Build freetype (without harfbuzz)')
8✔
85
            config_args = config_args.union(
8✔
86
                {'--disable-static',
87
                 '--enable-shared',
88
                 '--with-harfbuzz=no',
89
                 '--with-zlib=yes',
90
                 }
91
            )
92
        elif not with_harfbuzz:
×
UNCOV
93
            info('Build freetype for First time (without harfbuzz)')
×
94
            # This time we will build our freetype library as static because we
95
            # want that the harfbuzz library to have the necessary freetype
96
            # symbols/functions, so we avoid to have two freetype shared
97
            # libraries which will be confusing and harder to link with them
UNCOV
98
            config_args = config_args.union(
×
99
                {'--disable-shared', '--with-harfbuzz=no', '--with-zlib=no'}
100
            )
101
        else:
102
            info('Build freetype for Second time (with harfbuzz)')
×
UNCOV
103
            config_args = config_args.union(
×
104
                {'--disable-static',
105
                 '--enable-shared',
106
                 '--with-harfbuzz=yes',
107
                 '--with-zlib=yes',
108
                 }
109
            )
110
        info('Configure args are:\n\t-{}'.format('\n\t-'.join(config_args)))
8✔
111

112
        # Build freetype library
113
        with current_directory(self.get_build_dir(arch.arch)):
8✔
114
            configure = sh.Command('./configure')
8✔
115
            shprint(configure, *config_args, _env=env)
8✔
116
            shprint(sh.make, '-j', str(cpu_count()), _env=env)
8✔
117

118
            if not with_harfbuzz and harfbuzz_in_recipes:
8!
UNCOV
119
                info('Installing freetype (first time build without harfbuzz)')
×
120
                # First build, install the compiled lib, and clean build env
121
                shprint(sh.make, 'install', _env=env)
×
UNCOV
122
                shprint(sh.make, 'distclean', _env=env)
×
123

124
    def install_libraries(self, arch):
8✔
125
        # This library it's special because the first time we built it may not
126
        # generate the expected library, because it can depend on harfbuzz, so
127
        # we will make sure to only install it when the library exists
128
        if not exists(list(self.get_libraries(arch))[0]):
×
129
            return
×
UNCOV
130
        self.install_libs(arch, *self.get_libraries(arch))
×
131

132

133
recipe = FreetypeRecipe()
8✔
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