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

kivy / python-for-android / 17939140907

23 Sep 2025 07:41AM UTC coverage: 59.122% (-0.05%) from 59.168%
17939140907

Pull #3218

github

web-flow
Merge bb02aeff6 into 17e16d46d
Pull Request #3218: `opencv`: fix build

1060 of 2389 branches covered (44.37%)

Branch coverage included in aggregate %.

1 of 8 new or added lines in 1 file covered. (12.5%)

1 existing line in 1 file now uncovered.

4958 of 7790 relevant lines covered (63.65%)

2.53 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
4✔
2
from os.path import join
4✔
3

4
import sh
4✔
5

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

10

11
class OpenCVRecipe(NDKRecipe):
4✔
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'
4✔
19
    url = 'https://github.com/opencv/opencv/archive/{version}.zip'
4✔
20
    depends = ['numpy']
4✔
21
    patches = ['patches/p4a_build.patch']
4✔
22
    generated_libraries = [
4✔
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):
4✔
40
        return join(self.get_build_dir(arch.arch), 'build', 'lib', arch.arch)
×
41

42
    def get_recipe_env(self, arch):
4✔
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):
4✔
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))
NEW
71
            python_include_numpy = join(
×
72
                self.ctx.get_python_install_dir(arch.arch), "numpy/_core/include",
73
            )
74

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
NEW
142
            link_txt = 'modules/python3/CMakeFiles/opencv_python3.dir/link.txt'
×
NEW
143
            with open(link_txt, 'r+') as f:
×
NEW
144
                content = f.read().replace('-version', ' ')
×
NEW
145
                f.seek(0)
×
NEW
146
                f.write(content)
×
NEW
147
                f.truncate()
×
148

UNCOV
149
            shprint(sh.make, '-j' + str(cpu_count()), 'opencv_python' + python_major)
×
150
            # Install python bindings (cv2.so)
151
            shprint(sh.cmake, '-DCOMPONENT=python', '-P', './cmake_install.cmake')
×
152
            # Copy third party shared libs that we need in our final apk
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()
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