• 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

30.77
/pythonforandroid/recipes/opencv/__init__.py
1
from multiprocessing import cpu_count
8✔
2
from os.path import join
8✔
3

4
import sh
8✔
5

6
from pythonforandroid.logger import shprint
8✔
7
from pythonforandroid.recipe import NDKRecipe
8✔
8
from pythonforandroid.util import current_directory, ensure_dir
8✔
9

10

11
class OpenCVRecipe(NDKRecipe):
8✔
12
    '''
13
    .. versionchanged:: 0.7.1
14
        rewrote recipe to support the python bindings (cv2.so) and enable the
15
        build of most of the libraries of the opencv's package, so we can
16
        process images, videos, objects, photos...
17
    '''
18
    version = '4.12.0'
8✔
19
    url = 'https://github.com/opencv/opencv/archive/{version}.zip'
8✔
20
    depends = ['numpy']
8✔
21
    patches = ['patches/p4a_build.patch']
8✔
22
    generated_libraries = [
8✔
23
        'libopencv_features2d.so',
24
        'libopencv_imgproc.so',
25
        'libopencv_stitching.so',
26
        'libopencv_calib3d.so',
27
        'libopencv_flann.so',
28
        'libopencv_ml.so',
29
        'libopencv_videoio.so',
30
        'libopencv_core.so',
31
        'libopencv_highgui.so',
32
        'libopencv_objdetect.so',
33
        'libopencv_video.so',
34
        'libopencv_dnn.so',
35
        'libopencv_imgcodecs.so',
36
        'libopencv_photo.so',
37
    ]
38

39
    def get_lib_dir(self, arch):
8✔
40
        return join(self.get_build_dir(arch.arch), 'build', 'lib', arch.arch)
×
41

42
    def get_recipe_env(self, arch):
8✔
43
        env = super().get_recipe_env(arch)
×
44
        env['ANDROID_NDK'] = self.ctx.ndk_dir
×
45
        env['ANDROID_SDK'] = self.ctx.sdk_dir
×
46
        return env
×
47

48
    def build_arch(self, arch):
8✔
49
        build_dir = join(self.get_build_dir(arch.arch), 'build')
×
50
        ensure_dir(build_dir)
×
51

52
        opencv_extras = []
×
53
        if 'opencv_extras' in self.ctx.recipe_build_order:
×
54
            opencv_extras_dir = self.get_recipe(
×
55
                'opencv_extras', self.ctx).get_build_dir(arch.arch)
56
            opencv_extras = [
×
57
                f'-DOPENCV_EXTRA_MODULES_PATH={opencv_extras_dir}/modules',
58
                '-DBUILD_opencv_legacy=OFF',
59
            ]
60

61
        with current_directory(build_dir):
×
62
            env = self.get_recipe_env(arch)
×
63

64
            python_major = self.ctx.python_recipe.version[0]
×
65
            python_include_root = self.ctx.python_recipe.include_root(arch.arch)
×
66
            python_site_packages = self.ctx.get_site_packages_dir(arch)
×
67
            python_link_root = self.ctx.python_recipe.link_root(arch.arch)
×
68
            python_link_version = self.ctx.python_recipe.link_version
×
69
            python_library = join(python_link_root,
×
70
                                  'libpython{}.so'.format(python_link_version))
71
            python_include_numpy = join(
×
72
                self.ctx.get_python_install_dir(arch.arch), "numpy/_core/include",
73
            )
74

UNCOV
75
            shprint(sh.cmake,
×
76
                    '-DP4A=ON',
77
                    '-DANDROID_ABI={}'.format(arch.arch),
78
                    '-DANDROID_STANDALONE_TOOLCHAIN={}'.format(self.ctx.ndk_dir),
79
                    '-DANDROID_NATIVE_API_LEVEL={}'.format(self.ctx.ndk_api),
80
                    '-DANDROID_EXECUTABLE={}/tools/android'.format(env['ANDROID_SDK']),
81
                    '-DANDROID_SDK_TOOLS_VERSION=6514223',
82
                    '-DANDROID_PROJECTS_SUPPORT_GRADLE=ON',
83

84
                    '-DCMAKE_TOOLCHAIN_FILE={}'.format(
85
                        join(self.ctx.ndk_dir, 'build', 'cmake',
86
                             'android.toolchain.cmake')),
87
                    # Make the linkage with our python library, otherwise we
88
                    # will get dlopen error when trying to import cv2's module.
89
                    '-DCMAKE_SHARED_LINKER_FLAGS=-L{path} -lpython{version}'.format(
90
                        path=python_link_root,
91
                        version=python_link_version),
92

93
                    '-DBUILD_WITH_STANDALONE_TOOLCHAIN=ON',
94
                    # Force to build as shared libraries the cv2's dependent
95
                    # libs or we will not be able to link with our python
96
                    '-DBUILD_SHARED_LIBS=ON',
97
                    '-DBUILD_STATIC_LIBS=OFF',
98

99
                    # Disable some opencv's features
100
                    '-DBUILD_opencv_java=OFF',
101
                    '-DBUILD_opencv_java_bindings_generator=OFF',
102
                    # '-DBUILD_opencv_highgui=OFF',
103
                    # '-DBUILD_opencv_imgproc=OFF',
104
                    # '-DBUILD_opencv_flann=OFF',
105
                    '-DBUILD_TESTS=OFF',
106
                    '-DBUILD_PERF_TESTS=OFF',
107
                    '-DENABLE_TESTING=OFF',
108
                    '-DBUILD_EXAMPLES=OFF',
109
                    '-DBUILD_ANDROID_EXAMPLES=OFF',
110

111
                    # Force to only build our version of python
112
                    '-DBUILD_OPENCV_PYTHON{major}=ON'.format(major=python_major),
113
                    '-DBUILD_OPENCV_PYTHON{major}=OFF'.format(
114
                        major='2' if python_major == '3' else '3'),
115

116
                    # Force to install the `cv2.so` library directly into
117
                    # python's site packages (otherwise the cv2's loader fails
118
                    # on finding the cv2.so library)
119
                    '-DOPENCV_SKIP_PYTHON_LOADER=ON',
120
                    '-DOPENCV_PYTHON{major}_INSTALL_PATH={site_packages}'.format(
121
                        major=python_major, site_packages=python_site_packages),
122

123
                    # Define python's paths for: exe, lib, includes, numpy...
124
                    '-DPYTHON_DEFAULT_EXECUTABLE={}'.format(self.ctx.hostpython),
125
                    '-DPYTHON{major}_EXECUTABLE={host_python}'.format(
126
                        major=python_major, host_python=self.ctx.hostpython),
127
                    '-DPYTHON{major}_INCLUDE_PATH={include_path}'.format(
128
                        major=python_major, include_path=python_include_root),
129
                    '-DPYTHON{major}_LIBRARIES={python_lib}'.format(
130
                        major=python_major, python_lib=python_library),
131
                    '-DPYTHON{major}_NUMPY_INCLUDE_DIRS={numpy_include}'.format(
132
                        major=python_major, numpy_include=python_include_numpy),
133
                    '-DPYTHON{major}_PACKAGES_PATH={site_packages}'.format(
134
                        major=python_major, site_packages=python_site_packages),
135

136
                    *opencv_extras,
137

138
                    self.get_build_dir(arch.arch),
139
                    _env=env)
140

141
            # patch link.txt for unsupported flag
UNCOV
142
            link_txt = 'modules/python3/CMakeFiles/opencv_python3.dir/link.txt'
×
143
            with open(link_txt, 'r+') as f:
×
UNCOV
144
                content = f.read().replace('-version', ' ')
×
UNCOV
145
                f.seek(0)
×
UNCOV
146
                f.write(content)
×
UNCOV
147
                f.truncate()
×
148

UNCOV
149
            shprint(sh.make, '-j' + str(cpu_count()), 'opencv_python' + python_major)
×
150
            # Install python bindings (cv2.so)
UNCOV
151
            shprint(sh.cmake, '-DCOMPONENT=python', '-P', './cmake_install.cmake')
×
152
            # Copy third party shared libs that we need in our final apk
UNCOV
153
            sh.cp('-a', sh.glob('./lib/{}/lib*.so'.format(arch.arch)),
×
154
                  self.ctx.get_libs_dir(arch.arch))
155

156

157
recipe = OpenCVRecipe()
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