From 753ef181281a407982305899cae3f2fa68d12a2b Mon Sep 17 00:00:00 2001
From: Andre Miras <andre.miras@gmail.com>
Date: Fri, 1 Feb 2019 01:23:27 +0100
Subject: [PATCH] Fixes opencv compilation, fixes #1313

Updates to latest opencv version `4.0.1`.
The compilation was tested on host/target python3 and produced
`libopencv_core.a` & `libopencv_ml.a` static libraries.
Runtime wasn't tested.
---
 ci/constants.py                               |  2 -
 pythonforandroid/recipes/opencv/__init__.py   | 46 +++++++------
 .../opencv/patches/p4a_build-2.4.10.1.patch   | 66 -------------------
 3 files changed, 22 insertions(+), 92 deletions(-)
 delete mode 100644 pythonforandroid/recipes/opencv/patches/p4a_build-2.4.10.1.patch

diff --git a/ci/constants.py b/ci/constants.py
index fdfb87742f..3c51845afc 100644
--- a/ci/constants.py
+++ b/ci/constants.py
@@ -82,8 +82,6 @@ class TargetPython(Enum):
     # requires `libpq-dev` system dependency e.g. for `pg_config` binary
     'psycopg2',
     'netifaces',
-    # https://github.com/kivy/python-for-android/issues/1315 ?
-    'opencv',
     'protobuf_cpp',
     # most likely some setup in the Docker container, because it works in host
     'pyjnius', 'pyopenal',
diff --git a/pythonforandroid/recipes/opencv/__init__.py b/pythonforandroid/recipes/opencv/__init__.py
index 0e51450991..169aa88c5e 100644
--- a/pythonforandroid/recipes/opencv/__init__.py
+++ b/pythonforandroid/recipes/opencv/__init__.py
@@ -9,45 +9,43 @@
 
 
 class OpenCVRecipe(NDKRecipe):
-    version = '2.4.10.1'
-    url = 'https://github.com/Itseez/opencv/archive/{version}.zip'
-    # md5sum = '2ddfa98e867e6611254040df841186dc'
+    version = '4.0.1'
+    url = 'https://github.com/opencv/opencv/archive/{version}.zip'
     depends = ['numpy']
-    patches = ['patches/p4a_build-2.4.10.1.patch']
-    generated_libraries = ['cv2.so']
-
-    def prebuild_arch(self, arch):
-        self.apply_patches(arch)
 
     def get_recipe_env(self, arch):
         env = super(OpenCVRecipe, self).get_recipe_env(arch)
-        env['PYTHON_ROOT'] = self.ctx.get_python_install_dir()
         env['ANDROID_NDK'] = self.ctx.ndk_dir
         env['ANDROID_SDK'] = self.ctx.sdk_dir
-        env['SITEPACKAGES_PATH'] = self.ctx.get_site_packages_dir()
         return env
 
+    def should_build(self, arch):
+        return True
+
     def build_arch(self, arch):
-        with current_directory(self.get_build_dir(arch.arch)):
+        build_dir = os.path.join(self.get_build_dir(arch.arch), 'build')
+        shprint(sh.mkdir, '-p', build_dir)
+        with current_directory(build_dir):
             env = self.get_recipe_env(arch)
-            cvsrc = self.get_build_dir(arch.arch)
-            lib_dir = os.path.join(self.ctx.get_python_install_dir(), "lib")
-
             shprint(sh.cmake,
-                    '-DP4A=ON', '-DANDROID_ABI={}'.format(arch.arch),
-                    '-DCMAKE_TOOLCHAIN_FILE={}/platforms/android/android.toolchain.cmake'.format(cvsrc),
-                    '-DPYTHON_INCLUDE_PATH={}/include/python2.7'.format(env['PYTHON_ROOT']),
-                    '-DPYTHON_LIBRARY={}/lib/libpython2.7.so'.format(env['PYTHON_ROOT']),
-                    '-DPYTHON_NUMPY_INCLUDE_DIR={}/numpy/core/include'.format(env['SITEPACKAGES_PATH']),
+                    '-DANDROID_ABI={}'.format(arch.arch),
+                    '-DCMAKE_TOOLCHAIN_FILE={}/build/cmake/android.toolchain.cmake'.format(self.ctx.ndk_dir),
+                    '-DPYTHON_NUMPY_INCLUDE_DIR={}/numpy/core/include'.format(self.ctx.get_site_packages_dir()),
                     '-DANDROID_EXECUTABLE={}/tools/android'.format(env['ANDROID_SDK']),
-                    '-DBUILD_TESTS=OFF', '-DBUILD_PERF_TESTS=OFF',
+                    '-DBUILD_TESTS=OFF', '-DBUILD_PERF_TESTS=OFF', '-DENABLE_TESTING=OFF',
                     '-DBUILD_EXAMPLES=OFF', '-DBUILD_ANDROID_EXAMPLES=OFF',
-                    '-DPYTHON_PACKAGES_PATH={}'.format(env['SITEPACKAGES_PATH']),
-                    cvsrc,
+                    '-DBUILD_opencv_imgproc=OFF', '-DBUILD_opencv_flann=OFF',
+                    '-DBUILD_opencv_python3=ON',
+                    '-DBUILD_WITH_STANDALONE_TOOLCHAIN=ON',
+                    '-DPYTHON_PACKAGES_PATH={}'.format(self.ctx.get_site_packages_dir()),
+                    '-DANDROID_STANDALONE_TOOLCHAIN={}'.format(self.ctx.ndk_dir),
+                    '-DANDROID_NATIVE_API_LEVEL={}'.format(self.ctx.android_api),
+                    self.get_build_dir(arch.arch),
                     _env=env)
-            shprint(sh.make, '-j', str(cpu_count()), 'opencv_python')
+            shprint(sh.make, '-j', str(cpu_count()))
             shprint(sh.cmake, '-DCOMPONENT=python', '-P', './cmake_install.cmake')
-            sh.cp('-a', sh.glob('./lib/{}/lib*.so'.format(arch.arch)), lib_dir)
+            sh.cp('-a', sh.glob('./lib/{}/lib*.a'.format(arch.arch)), self.ctx.get_libs_dir(arch.arch))
+            self.ctx.get_libs_dir(arch.arch)
 
 
 recipe = OpenCVRecipe()
diff --git a/pythonforandroid/recipes/opencv/patches/p4a_build-2.4.10.1.patch b/pythonforandroid/recipes/opencv/patches/p4a_build-2.4.10.1.patch
deleted file mode 100644
index a7a60aa3b3..0000000000
--- a/pythonforandroid/recipes/opencv/patches/p4a_build-2.4.10.1.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-diff --git a/cmake/OpenCVDetectPython.cmake b/cmake/OpenCVDetectPython.cmake
-index 31c2c1e..c890917 100644
---- a/cmake/OpenCVDetectPython.cmake
-+++ b/cmake/OpenCVDetectPython.cmake
-@@ -36,7 +36,7 @@ if(PYTHON_EXECUTABLE)
-     unset(PYTHON_VERSION_FULL)
-   endif()
- 
--  if(NOT ANDROID AND NOT IOS)
-+  if(P4A OR NOT ANDROID AND NOT IOS)
-     ocv_check_environment_variables(PYTHON_LIBRARY PYTHON_INCLUDE_DIR)
-     if(CMAKE_CROSSCOMPILING)
-       find_host_package(PythonLibs ${PYTHON_VERSION_MAJOR_MINOR})
-@@ -51,7 +51,7 @@ if(PYTHON_EXECUTABLE)
-     endif()
-   endif()
- 
--  if(NOT ANDROID AND NOT IOS)
-+  if(P4A OR NOT ANDROID AND NOT IOS)
-     if(CMAKE_HOST_UNIX)
-       execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import *; print get_python_lib()"
-                       RESULT_VARIABLE PYTHON_CVPY_PROCESS
-@@ -117,7 +117,7 @@ if(PYTHON_EXECUTABLE)
-                         OUTPUT_STRIP_TRAILING_WHITESPACE)
-       endif()
-     endif()
--  endif(NOT ANDROID AND NOT IOS)
-+  endif(P4A OR NOT ANDROID AND NOT IOS)
- 
-   if(BUILD_DOCS)
-     find_host_program(SPHINX_BUILD sphinx-build)
-diff --git a/modules/python/CMakeLists.txt b/modules/python/CMakeLists.txt
-index 3c0f2fd..7ba234a 100644
---- a/modules/python/CMakeLists.txt
-+++ b/modules/python/CMakeLists.txt
-@@ -5,7 +5,7 @@
- if(WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug")
-   ocv_module_disable(python)
- endif()
--if(ANDROID OR IOS OR NOT PYTHONLIBS_FOUND OR NOT PYTHON_USE_NUMPY)
-+if(ANDROID AND NOT P4A OR IOS OR NOT PYTHONLIBS_FOUND OR NOT PYTHON_USE_NUMPY)
-   ocv_module_disable(python)
- endif()
- 
-diff --git a/modules/androidcamera/src/camera_activity.cpp b/modules/androidcamera/src/camera_activity.cpp
-index 84db3e1..4222526 100644
---- a/modules/androidcamera/src/camera_activity.cpp
-+++ b/modules/androidcamera/src/camera_activity.cpp
-@@ -7,6 +7,7 @@
- #include <string>
- #include <vector>
- #include <algorithm>
-+#include <stdlib.h>
- #include <opencv2/core/version.hpp>
- #include "camera_activity.hpp"
- #include "camera_wrapper.h"
-@@ -342,6 +343,8 @@ std::string CameraWrapperConnector::getPathLibFolder()
- 
-                 char* pathEnd = strrchr(pathBegin, '/');
-                 pathEnd[1] = 0;
-+                pathBegin = realpath((std::string(pathBegin)+"../../../../lib").c_str(), lineBuf);
-+                pathBegin = strcat(pathBegin, "/");
- 
-                 LOGD("Libraries folder found: %s", pathBegin);
- 
-