[Android] 안드로이드 용 OpenCV 빌드하기-2

2024. 1. 23. 10:48모바일프로그래밍/안드로이드

728x90

저번글에 계속해서 안드로이드 용 OpenCV 를 빌드 해보도록 합니다.

OpenCV 버전은 4.8.1 현재 최신 버전입니다.

 

 

[Android] 안드로이드 용 OpenCV 빌드하기

하다가 만 저번 글에서 ndk version 을 바꾸어 주었는 데... 가만 생각해 보니, 그 버전에서 컴파일 된 안...

blog.naver.com

 

opencv 사이트 연동하기 - git

git 으로 opencv 사이트를 연동하기로 했습니다. 왜냐하면 갑자기 contribute 모듈도 빌드하고 싶어 졌더거든요...

모듈을 컴파일하다고 다음오류가 떨어졌습니다.

no matching function for call to 'v_shr'
 

뜬금없기도하고...황당하기도하고..

아래처럼 하라고 하는 데, 별로 좋은 옵션은 아닌 것 같네요...

-DBUILD_opencv_xphoto=OFF
-DBUILD_opencv_optflow=OFF
-DBUILD_opencv_rgbd=OFF
 

다음 글에서 약간의 힌트를 얻었습니다.

주 내용은 모듈과 코어 라이브러리 버전을 잘 맞추라는 조언을 하고 있네요..

다음과 같이 git 명령어로 연동하도록 합니다.

참고로 git의 환경 설정은 다음과 같이 해 두었습니다.

  • OpenCV 모듈의 경우
@ECHO git clone https://github.com/opencv/opencv
@ECHO cd opencv
@ECHO git checkout -b 4.8.1 4.8.1
@ECHO git remote update
 
  • Opencv-contrib 모듈의 경우
@ECHO git clone https://github.com/opencv/opencv_contrib.git
@ECHO cd opencv_contrib
@ECHO git checkout -b 4.8.1 4.8.1
 

OpenCV 빌드하기

OpenCV 를 안드로이드 용으로 다음과 같이 통합 빌드 하기로 했습니다.

우선 캐시를 다음과 같이 지워주고...

cmake --build . --target clean
 

 

 

opencv 자바모듈 빌드하기

자바모듈을 빌드 하기 위해서, 여러가지 시도 끝에 다음과 같이 환경 설정을 잡아보았습니다.

우선,

  • 자바는 19 버전을 사용하고,
  • gradle 버전은 8.1
  • 안드로이드 gradle 플러그인 버전은 7.4.0

에 맞췄습니다. 왜 이렇게 맞췄냐고 한다면 우선 다음과 같이 안드로이드 개발자 사이트에서 확인 한 내용 대로 gradle 버전과 플러그인 버전을 맞추려고 했습니다.

https://developer.android.com/studio/releases/gradle-plugin?hl=ko

 

Android Gradle 플러그인 출시 노트  |  Android 개발자  |  Android Developers

Android 스튜디오 빌드 시스템은 Gradle을 기반으로 하며 Android Gradle 플러그인에는 Android 앱을 빌드하는 데 사용하는 몇 가지 추가 기능이 있습니다.

developer.android.com

 

뭐.. 아래와 같이 최소 gradle 버전이 현재 8.1로 맞췄으니, 플러그인 버전은 약간 내려서 7.4로 맞춘거죠.

환경설정 - 자바

위의 내용과 맞춰서 자바의 환경설정은 다음과 같이 맞췄습니다.

SET JAVA_HOME=C:\DEV\SDK\JDK\jdk-19.0.1
SET ANDROID_HOME=C:\DEV\SDK\android-sdk

SET OPECV_VER=4.8.1
SET NDK_VER=26.1.10909125
SET GRADLE_VER=8.1
@ECHO SET ARCH=armeabi-v7a
SET ARCH=arm64-v8a

SET GRADLE_HOME=C:\DEV\Tools\gradle-%GRADLE_VER%
SET ANT_HOME=C:\DEV\Tools\apache-ant-1.9.16
SET PYTHON_HOME=C:\DEV\SDK\anaconda3
SET ANDROID_NDK_HOME=%ANDROID_HOME%\ndk\%NDK_VER%

SET GRADLE_USER_HOME=%GRADLE_HOME%
SET ANDROID_NDK=%ANDROID_NDK_HOME%
SET CMAKE_HOME=%ANDROID_HOME%\cmake\3.22.1
SET CV_HOME=C:\DEV\SDK\opencv-%OPECV_VER%

SET PATH=%PYTHON_HOME%;%ANT_HOME%\bin;%CMAKE_HOME%\bin;%JAVA_HOME%\bin;%ANDROID_HOME%\cmdline-tools\bin;.;%PATH%
 

gradle을 다운로드 받고 여전히 이 gradle 환경을 opencv 개발을 위해서 사용해야 할 것입니다.

따라서 아래 환경 설정 변수가 중요 합니다.

SET GRADLE_HOME=C:\DEV\Tools\gradle-%GRADLE_VER%
...
SET GRADLE_USER_HOME=%GRADLE_HOME%
 

 

빌드 스크립트 만들기

위의 내용과 맞춰서 빌드 스크립트를 다음에 맞춥니다.

cmake.exe -G"MinGW Makefiles" ^
-DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%\build\cmake\android.toolchain.cmake   ^
-DCMAKE_MAKE_PROGRAM=%ANDROID_NDK%\prebuilt\windows-x86_64\bin\make.exe ^
-DCMAKE_INSTALL_PREFIX:PATH=%CV_HOME%/output/%ARCH%/lib/ ^
-DBUILD_SHARED_LIBS=OFF  ^
-DBUILD_JAVA=ON   ^
-DBUILD_TESTS=OFF  ^
-DBUILD_PERF_TESTS=OFF  ^
-DBUILD_ANDROID_EXAMPLES=OFF  ^
-DBUILD_opencv_java=ON   ^
-DBUILD_FAT_JAVA_LIB=ON ^
-DBUILD_ANDROID_PROJECTS=ON ^
-DCMAKE_BUILD_TYPE=Release ^
-DPARALLEL_ENABLE_PLUGINS=OFF  ^
-DANDROID_SDK=%ANDROID_HOME%   ^
-DANDROID_GRADLE_PLUGIN_VERSION=7.4.0 ^
-DANDROID_NATIVE_API_LEVEL=android-24 ^
-DGRADLE_VERSION=%GRADLE_VER% ^
-DANDROID_ABI=%ARCH% ^
-DOPENCV_EXTRA_MODULES_PATH=C:\DEV\SDK\opencv-%OPECV_VER%\opencv_contrib\modules  ^
-DJAVA_AWT_INCLUDE_PATH:PATH=%JAVA_HOME%\include   ^
-DJAVA_AWT_LIBRARY:FILEPATH=%JAVA_HOME%\include\jawt.h   ^
-DJAVA_INCLUDE_PATH:PATH=%JAVA_HOME%\include   ^
-DJAVA_INCLUDE_PATH2:PATH=%JAVA_HOME%\include\win32   ^
-DJAVA_JVM_LIBRARY:FILEPATH=%JAVA_HOME%\include\jni.h   ^
-DANT_EXECUTABLE:FILEPATH=%ANT_HOME%/bin/ant.bat ..
 

위 스크립트 중에서 다음 선언부가 좀 중요할 듯 하네요...

-DANDROID_GRADLE_PLUGIN_VERSION=7.4.0
 

위에 선언은 다음의 build.gradle.in 파일 내에 존재 합니다.

~\opencv-4.8.1\opencv\samples\android\build.gradle.in
 

그리고 해당 파일 내에 project.android 는 다음과 같은 오류를 냅니다.

최상위 레벨에서는 android 블럭을 사용하지 못한다는 것이고, gradle 버전이 많이 낮은 것을 여전히 사용해서 그런 듯 합니다. 따라서 해당 파일 내에 있는 android 블럭을 다 주석 처리 해 주었습니다.

코틀린도 안쓰니까 버립니다...

~\opencv-4.8.1\opencv\samples\android\build.gradle.in
 
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:@ANDROID_GRADLE_PLUGIN_VERSION@'
//        classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:@KOTLIN_PLUGIN_VERSION@'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

//allprojects {
//    gradle.projectsEvaluated {
//        tasks.withType(JavaCompile) {
//            options.compilerArgs << "-Xlint:unchecked"
//            options.compilerArgs << "-Xlint:deprecation"
//        }
//    }
//}

def opencv_strict_build_configuration = @ANDROID_STRICT_BUILD_CONFIGURATION@;

gradle.afterProject { project ->
    if (project.pluginManager.hasPlugin('com.android.application')
            || project.pluginManager.hasPlugin('com.android.library')
            || project.pluginManager.hasPlugin('com.android.test')
            || project.pluginManager.hasPlugin('com.android.feature') ) {
        if (true) {
            gradle.println("Override build ABIs for the project ${project.name}")
//            project.android {
//                splits {
//                    abi {
//                        enable true
//                        universalApk false
//                        @ANDROID_ABI_FILTER@
//                    }
//                }
//            }
        }

        if (true) {
            gradle.println("Override lintOptions for the project ${project.name}")
//            project.android {
//                lintOptions {
//                    // checkReleaseBuilds false
//                    abortOnError false
//                }
//            }
        }

        // (you still need to re-build OpenCV with debug information to debug it)
        if (true) {
            gradle.println("Override doNotStrip-debug for the project ${project.name}")
//            project.android {
//                buildTypes {
//                    debug {
//                        packagingOptions {
//                            doNotStrip '**/*.so'  // controlled by OpenCV CMake scripts
//                        }
//                    }
//                }
//            }
        }
        if (false || project.hasProperty("doNotStrip")) {
            gradle.println("Override doNotStrip-release for the project ${project.name}")
//            project.android {
//                buildTypes {
//                    release {
//                        packagingOptions {
//                            doNotStrip '**/*.so'  // controlled by OpenCV CMake scripts
//                        }
//                    }
//                }
//            }
        }

        // Android Gradle Plugin (AGP) 3.5+ is required
        // https://github.com/android/ndk-samples/wiki/Configure-NDK-Path
//        def isNdkVersionSupported = project.android.metaClass.getProperties().find { it.name == 'ndkVersion' } != null
//        if ((false || opencv_strict_build_configuration) && isNdkVersionSupported) {
//            gradle.println("Override ndkVersion for the project ${project.name}")
//            project.android {
//                ndkVersion '@ANDROID_NDK_REVISION@'
//            }
//        }
    }
}
 
~\opencv-4.8.1\opencv\modules\java\android_sdk\build.gradle.in
 
apply plugin: 'com.android.library'
//@KOTLIN_PLUGIN_DECLARATION@

def openCVersionName = "@OPENCV_VERSION@"
def openCVersionCode = ((@OPENCV_VERSION_MAJOR@ * 100 + @OPENCV_VERSION_MINOR@) * 100 + @OPENCV_VERSION_PATCH@) * 10 + 0
println "OpenCV: " +openCVersionName + " " + project.buildscript.sourceFile

android {
    @OPENCV_ANDROID_NAMESPACE_DECLARATION@
    compileSdkVersion @ANDROID_COMPILE_SDK_VERSION@

    defaultConfig {
        minSdkVersion @ANDROID_MIN_SDK_VERSION@
        targetSdkVersion @ANDROID_TARGET_SDK_VERSION@

        versionCode openCVersionCode
        versionName openCVersionName

        externalNativeBuild {
            cmake {
                arguments "-DANDROID_STL=@ANDROID_STL@"
                targets "opencv_jni_shared"
            }
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_@ANDROID_GRADLE_JAVA_VERSION_INIT@
        targetCompatibility JavaVersion.VERSION_@ANDROID_GRADLE_JAVA_VERSION_INIT@
    }

    @ANDROID_GRADLE_BUILD_FEATURE_AIDL@

    buildTypes {
        debug {
            packagingOptions {
                doNotStrip '**/*.so'  // controlled by OpenCV CMake scripts
            }
        }
        release {
            packagingOptions {
                doNotStrip '**/*.so'  // controlled by OpenCV CMake scripts
            }
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }

    sourceSets {
        main {
            jniLibs.srcDirs = ['native/libs']
            java.srcDirs = ['java/src']
            aidl.srcDirs = ['java/src']
            res.srcDirs = ['java/res']
            manifest.srcFile 'java/AndroidManifest.xml'
        }
    }

    externalNativeBuild {
        cmake {
            path (project.projectDir.toString() + '/libcxx_helper/CMakeLists.txt')
        }
    }
}
dependencies {
}
 

음...gradle을 공부해 봐야 하는 걸까??

 

참고로 여기까지 내용을 다 확인하지 않고 삽질을 하게 되면 나는 오류들입니다.

* What went wrong:
A problem occurred configuring project ':opencv'.
> Could not find method android() for arguments [build_5k2sszaran8ort15i5eiv7y7a$_run_closure3$_closure5@400ddbab] 
on project ':opencv' of type org.gradle.api.Project.
 
Failed to apply plugin 'com.android.library'
 
Failed to notify project evaluation listener.
   > org/gradle/api/plugins/MavenPlugin
 

일단 위의 오류가 난다고 싶으면, 환경설정을 잘 못 맞춰서 그런거라고 생각하면 될 듯 하네요...

 

그 다음으로 주의 깊게 봐야 할 옵션은 저의 경우에는 다음의 것들이 있습니다.

-DANDROID_NATIVE_API_LEVEL=android-24
-DGRADLE_VERSION=%GRADLE_VER% <== 현재는 8.1
 
-DCMAKE_MAKE_PROGRAM=%ANDROID_NDK%\prebuilt\windows-x86_64\bin\make.exe
-DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%\build\cmake\android.toolchain.cmake
 

 

마지막으로 다음과 같이 빌드를 시작해 줍니다.

~\android-sdk\ndk\25.1.8937393\prebuilt\windows-x86_64\bin\make.exe -j8
 

그리고 두 개의 오류를 잡아 줍니다...왜? 몰라요...

음...gradle을 공부해 봐야 하는 걸까??

~\opencv-4.8.1\opencv\build\opencv_android\build.gradle
 
~\opencv-4.8.1\opencv\build\opencv_android\opencv\build.gradle
 
 

결과는 아래처럼 나오면 됩니다.

그러면 다음과 같이 실행 해 줍니다.

~\android-sdk\ndk\25.1.8937393\prebuilt\windows-x86_64\bin\make.exe install
 

최종적으로 4.8.1 버전으로 빌드 된 모습입니다.

이상.

 

728x90