ProgramingTip

Android Studio의 JNI 및 Gradle

bestdevel 2020. 10. 20. 07:55
반응형

Android Studio의 JNI 및 Gradle


내 앱에 추가 코드를 추가합니다. ../main/jni내 Eclipse 프로젝트 에서 모든 것이 있습니다. 내가 추가 한 ndk.dir=...나의에 local.properties. (실제로 무엇이 필요한지 잘 모르겠습니다. 놓친 것이 좋습니다.). 시도하고 빌드 할 때이 오류가 발생합니다.

Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.internal.LoggedErrorException: Failed to run command:
    /Users/me/android-ndk-r8e/ndk-build NDK_PROJECT_PATH=null 
APP_BUILD_SCRIPT=/Users/me/Project/app/build/ndk/debug/Android.mk APP_PLATFORM=android-19 
NDK_OUT=/Users/me/Project/app/build/ndk/debug/obj 
NDK_LIBS_OUT=/Users/me/Project/app/build/ndk/debug/lib APP_ABI=all

  Error Code:
    2
  Output:
    make: *** No rule to make target `/Users/me/Project/webapp/build/ndk/debug//Users/me/Project/app/src/main/jni/jni_part.cpp',
 needed by `/Users/me/Project/app/build/ndk/debug/obj/local/armeabi-v7a/objs/webapp//Users/me/Project/app/src/main/jni/jni_part.o'.  
Stop.

내가 무엇을해야 하나?

Android.mk :

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# OpenCV
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
include .../OpenCV-2.4.5-android-sdk/sdk/native/jni/OpenCV.mk

LOCAL_MODULE    := native_part
LOCAL_SRC_FILES := jni_part.cpp
LOCAL_LDLIBS +=  -llog -ldl

include $(BUILD_SHARED_LIBRARY)

Application.mk :

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-8

Gradle Build Tools 2.2.0 +-가장 가까운 NDK가 '마법'이라고 불립니다.

실험 모든 솔직히 NDK와 해커에 지쳐하지 않도록 노력하면서, 2.2.x의 Gradle 빌드 도구가 나왔고 이제는 제대로 작동합니다. 는을 구석으로입니다 키 externalNativeBuild및 포인팅 ndkBuild가 AT 인수 경로 Android.mk또는 변경 ndkBuildcmake과에서 경로를 가리 인수 CMakeLists.txt빌드 펼쳐.

android {
    compileSdkVersion 19
    buildToolsVersion "25.0.2"

    defaultConfig {
        minSdkVersion 19
        targetSdkVersion 19

        ndk {
            abiFilters 'armeabi', 'armeabi-v7a', 'x86'
        }

        externalNativeBuild {
            cmake {
                cppFlags '-std=c++11'
                arguments '-DANDROID_TOOLCHAIN=clang',
                        '-DANDROID_PLATFORM=android-19',
                        '-DANDROID_STL=gnustl_static',
                        '-DANDROID_ARM_NEON=TRUE',
                        '-DANDROID_CPP_FEATURES=exceptions rtti'
            }
        }
    }

    externalNativeBuild {
        cmake {
             path 'src/main/jni/CMakeLists.txt'
        }
        //ndkBuild {
        //   path 'src/main/jni/Android.mk'
        //}
    }
}

더 자세한 내용은 Google의 추가 페이지를 확인 하세요 .

이것이 당신은 ./gradlew installDebug수 있습니다 . 또한 gcc는 이제 Android NDK에서 지원이 중단 되었으나 NDK가 중단되었습니다.

Android Studio 정리 및 빌드 통합 지원 중단됨

다른 답변은 Android.mk파일 자동 생성을 방지하는 올바른 방법을 지적 하지만 Android Studio와 더 잘 통합하는 추가 단계를 수행하지 못합니다. 명령 줄로 필요한 필요없이 소스에서 실제로 정리하고 빌드하는 기능을 추가했습니다. 귀하의 local.properties파일이 필요합니다ndk.dir=/path/to/ndk

apply plugin: 'com.android.application'

android {
    compileSdkVersion 14
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "com.example.application"
        minSdkVersion 14
        targetSdkVersion 14

        ndk {
            moduleName "YourModuleName"
        }
    }

    sourceSets.main {
        jni.srcDirs = [] // This prevents the auto generation of Android.mk
        jniLibs.srcDir 'src/main/libs' // This is not necessary unless you have precompiled libraries in your project.
    }

    task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
        def ndkDir = android.ndkDirectory
        commandLine "$ndkDir/ndk-build",
                '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                '-j', Runtime.runtime.availableProcessors(),
                'all',
                'NDK_DEBUG=1'
    }

    task cleanNative(type: Exec, description: 'Clean JNI object files') {
        def ndkDir = android.ndkDirectory
        commandLine "$ndkDir/ndk-build",
                '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                'clean'
    }

    clean.dependsOn 'cleanNative'

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn buildNative
    }
}

dependencies {
    compile 'com.android.support:support-v4:20.0.0'
}

src/main/jni디렉토리는 프로젝트의 표준 레이아웃을 가정합니다. build.gradle파일 위치에서 jni최후의 최후는 최후의 방법 입니다.

Gradle- 문제가있는 사람들을 위해

Stack Overflow 답변 도 확인하십시오 .

gradle 버전과 일반 설정이 올바른 것이 정말 중요합니다. 이전 프로젝트가있는 경우 최신 Android Studio로 새 프로젝트를 제작하고 Google이 표준 프로젝트를 구현하는 것을 확인하는 것이 좋습니다. 또한 gradlew. 이 개발자를 gradle 버전 불일치로부터 보호합니다. 마지막으로 gradle 플러그인을 구성해야합니다.

그리고 최신 버전의 gradle 플러그인이 무엇인지 묻습니다. 도구 페이지를 확인하고 그에 따라 버전을 편집하십시오.

최종 제품-/ build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

// Running 'gradle wrapper' will generate gradlew - Getting gradle wrapper working and using it will save you a lot of pain.
task wrapper(type: Wrapper) {
    gradleVersion = '2.2'
}

// Look Google doesn't use Maven Central, they use jcenter now.
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.2.0'

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

allprojects {
    repositories {
        jcenter()
    }
}

확실히 gradle wrapper생성 gradlew파일 및 gradle/wrapper하위 디렉토리를 생성합니다. 이것은 큰 문제입니다.

ndkDirectory

이것은 여러 번 나타 났지만 android.ndkDirectory1.1 이후 폴더를 가져 오는 올바른 방법입니다. Gradle 프로젝트를 버전 1.0.0으로 마이그레이션 . 실험적 또는 고대 버전의 플러그인을 사용하는 경우 마일리지가 다를 수 있습니다.


gradle은 소스에 대한 절대 경로가있는 다른 Android.mk 파일을 생성하여 ndk 컴파일을 지원합니다. NDK는 OSX의 r9, Windows의 r9c 이후 절대 경로를 지원하므로 NDK를 r9 +로 업그레이드해야합니다.

gradle의 NDK 지원이 예비이므로 다른 문제가 발생할 수 있습니다. 그렇다면 다음을 설정하여 gradle에서 ndk 컴파일을 비활성화 할 수 있습니다.

sourceSets.main {
    jni.srcDirs = []
    jniLibs.srcDir 'src/main/libs'
}

ndk-build를 직접 호출하고 libs /에서 libs를 통합 할 수 있습니다.

btw, x86 용으로 컴파일하는 데 문제가 있습니까? APP_ABI에 포함되지 않은 것 같습니다.


제 경우에는 Windows에 있으며 위의 Cameron의 답변을 따르면 ndk-build.cmd 인 ndk-build의 전체 이름을 사용하는 경우에만 작동합니다 . 프로젝트정리하고 다시 빌드 한 다음 앱이 작동하기 전에 에뮬레이터다시 시작 해야합니다 (실제로 NDK에서 Android Studio로 샘플 HelloJni를 가져 왔습니다). 하지만 NDK 경로에 공백이 포함되어 있지 않은지 확인하세요 .

마지막으로 내 build.gradle은 다음과 같이 가득 차 있습니다.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.example.hellojni"
        minSdkVersion 4
        targetSdkVersion 4

        ndk {
            moduleName "hello-jni"
        }

        testApplicationId "com.example.hellojni.tests"
        testInstrumentationRunner "android.test.InstrumentationTestRunner"
    }
    sourceSets.main {
        jni.srcDirs = [] // This prevents the auto generation of Android.mk
//        sourceSets.main.jni.srcDirs = []
        jniLibs.srcDir 'src/main/libs' // This is not necessary unless you have precompiled libraries in your project.
    }

    task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
        def ndkDir = android.plugin.ndkFolder
        commandLine "$ndkDir/ndk-build.cmd",
                '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                '-j', Runtime.runtime.availableProcessors(),
                'all',
                'NDK_DEBUG=1'
    }

    task cleanNative(type: Exec, description: 'Clean JNI object files') {
        def ndkDir = android.plugin.ndkFolder
        commandLine "$ndkDir/ndk-build.cmd",
                '-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
                'clean'
    }

    clean.dependsOn 'cleanNative'

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn buildNative
    }

}


dependencies {
    compile 'com.android.support:support-v4:21.0.3'
}

OSX에 대한 내 문제는 gradle 버전이었습니다. Gradle이 내 Android.mk를 무시했습니다. 따라서이 옵션을 무시하고 대신 내 make를 사용하기 위해 다음 줄을 입력했습니다.

sourceSets.main.jni.srcDirs = []

android태그 내부 build.gradle.

나는 이것에 많은 시간을 낭비했다!


Android Studio 2.2는 ndk-build 및 cMake를 사용할 수있는 기능을 제공합니다. 그러나 Application.mk 지원을 위해 2.2.3까지 기다려야했습니다. 시도했지만 작동하지만 내 변수는 디버거에 표시되지 않습니다. 그래도 명령 줄을 통해 쿼리 할 수 ​​있습니다.

다음과 같이해야합니다.

externalNativeBuild{
   ndkBuild{
        path "Android.mk"
    }
}

defaultConfig {
  externalNativeBuild{
    ndkBuild {
      arguments "NDK_APPLICATION_MK:=Application.mk"
      cFlags "-DTEST_C_FLAG1"  "-DTEST_C_FLAG2"
      cppFlags "-DTEST_CPP_FLAG2"  "-DTEST_CPP_FLAG2"
      abiFilters "armeabi-v7a", "armeabi"
    }
  } 
}

http://tools.android.com/tech-docs/external-c-builds 참조

NB :externalNativeBuild 내부 의 추가 중첩은 defaultConfigAndroid Studio 2.2 Preview 5 (2016 년 7 월 8 일)에 도입 된 주요 변경 사항입니다. 위 링크에서 릴리스 정보를 참조하십시오.


모듈 build.gradle의 작업 필드에서 다음을 사용하지 않으면 오류가 발생합니다.

def ndkDir = plugins.getPlugin('com.android.application').sdkHandler.getNdkFolder()

나는 사람들이

def ndkDir = android.plugin.ndkFolder

def ndkDir = plugins.getPlugin('com.android.library').sdkHandler.getNdkFolder()

그러나 실제로 가져온 플러그인으로 변경할 때까지 둘 다 작동하지 않았습니다.

참고 URL : https://stackoverflow.com/questions/21096819/jni-and-gradle-in-android-studio

반응형