2017-12-09 9 views
0

Android Studio 3.0으로 업데이트되었으며 Android 앱의 기본 구성 요소를 빌드하기 위해 더 이상 사용되지 않는 NDK에서 CMake로 마이그레이션하려고합니다.Android Studio 네이티브 CMake 네이티브 용 구현이 없습니다.

cmake_minimum_required(VERSION 3.4.1) 
add_library(# Specifies the name of the library. 
     myappNative 

     # Sets the library as a shared library. 
     SHARED 

     # Provides a relative path to your source file(s). 
     src/main/cpp/src 
     ) 


include_directories(src/main/cpp/include) 
SET_TARGET_PROPERTIES(myappNative PROPERTIES LINKER_LANGUAGE CXX) 

(마지막 줄이 튜토리얼에서가 아니라 내가 그것을 추가하기 전에 오류를 얻고 있었다) : 여기 https://developer.android.com/studio/projects/configure-cmake.html에서 가이드를 따라하고 한

내 CMakeLists.txt 파일입니다.

/* DO NOT EDIT THIS FILE - it is machine generated */ 
#include <jni.h> 
/* Header for class com_myapp_system_Native */ 

#ifndef _Included_com_myapp_system_Native 
#define _Included_com_myapp_system_Native 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
* Class:  com_myapp_system_Native 
* Method: sign 
* Signature: ([Ljava/lang/String;)Ljava/lang/String; 
*/ 
JNIEXPORT jstring JNICALL Java_com_myapp_system_Native_sign 
    (JNIEnv *, jclass, jobjectArray); 

#ifdef __cplusplus 
} 
#endif 
#endif 

: 여기

public class Native { 

    static { 
     System.loadLibrary("myappNative"); 
    } 

    public native static String sign(String[] tokens); 
} 

이 ( javah에 의해 생성) 내 헤더 파일입니다

여기

enter image description here

내 기본 방법입니다 : 여기

내 폴더 구조 그리고 나는 C를 컴파일하는 해당 C++ 파일을 가지고있다. 바르게. 내 APK에 libmyapp.so 파일이 포함되어 있으며 예상대로 모든 것이 표시됩니다.

W/dalvikvm: No implementation found for native Lcom/myapp/system/Native;.sign:([Ljava/lang/String;)Ljava/lang/String; 

이 얹는 :이 얻을, 그럼 난 네이티브 메소드를 호출하려고하는 순간 (로그 캣)

D/dalvikvm: Trying to load lib /data/app-lib/com.myapp.myapp-1/libmyappNative.so 0x41e09aa0 
D/dalvikvm: Added shared lib /data/app-lib/com.myapp.myapp-1/libmyappNative.so 0x41e09aa0 

: 내 응용 프로그램은이 라이브러리를로드가 실행 시작, 빌드 :

E/AndroidRuntime: FATAL EXCEPTION: com.myapp.client.queue 
            Process: com.myapp.myapp, PID: 19542 
            java.lang.UnsatisfiedLinkError: Native method not found: com.myapp.system.Native.sign:([Ljava/lang/String;)Ljava/lang/String; 
             at com.myapp.system.Native.sign(Native Method) 
[...] 

그리고 내 응용 프로그램이 다운됩니다. 나는 Android NDK C++ JNI (no implementation found for native...)을 포함하여 이것에 관한 많은 질문을 보았지만 그 해결책도 도움이되지 않습니다. 로그에서

, 나는 참조 :

:app:externalNativeBuildDebug 
Build myappNative armeabi-v7a 
[1/1] Linking CXX shared library ../../../../build/intermediates/cmake/debug/obj/armeabi-v7a/libmyappNative.so 
:app:compileDebugSources 

괜찮을 것 같다있다.

또한 Proguard와 메소드 이름을 엉망으로 될 수 어딘가에 읽었습니다, 그래서 나 또한 너무 그것을 위해 규칙을 추가했습니다 :

-keep class com.myapp.system.Native

는하지만 아무것도 변경하는 경우 나도 몰라 . 여기

또한 내 Gradle을 파일의 관련 부분이다 : 나는 또한 JNI_OnLoad 방법을 구현하고 헤더에 선언 시도했습니다

android { 
    compileSdkVersion 26 
    buildToolsVersion '26.0.2' 

    defaultConfig { 
     applicationId "com.myapp.myapp" 
     minSdkVersion 16 
     targetSdkVersion 26 
     versionCode 2043 
     versionName "2.1" 
     ndk { 
      moduleName "myappNative" 
      cFlags "-DNATIVE_DEBUG=1" 
     } 

    } 


    externalNativeBuild { 
     cmake { 
      path 'CMakeLists.txt' 
     } 
    } 
} 

하지만 중 하나를 찾을 수하지 않는 것, 이는 오히려 특정 방법보다 내 구성 일반적으로 뭔가 단서가 될 수 있습니다

No JNI_OnLoad found in /data/app-lib/com.myapp.myapp-2/libmyappNative.so 0x41e10aa0, skipping init 

왜 내 기본 방법을 찾을 수없는 안드로이드입니까?

답변

1

튜토리얼 (SET_TARGET_PROPERTIES 추가)에없는 오류가 중요하다는 것이 분명합니다.

문제점을 발견했습니다. 내 CMakeLists.txt에서 나는 src/main/cpp/src이라는 폴더를 참조하고있었습니다. 실제로 어떤 파일도 컴파일하지 않았습니다. nm (ARM 버전)을 확인한 결과 .so 파일 안에 실제 방법이 없습니다. 그런 다음 CPP 파일 (컴파일하지 않아야 함)에 가비지를 추가했지만 빌드가 성공적으로 완료되었습니다. 컴파일되는 CPP 파일에 대한 나의 초기 가정은 부정확합니다 : 툴체인은 파일을 컴파일하려고하지 않았습니다. 명시 적으로 컴파일 할 파일을 나열해야하는 것 같습니다.

add_library(# Specifies the name of the library. 
     myappNative 

     # Sets the library as a shared library. 
     SHARED 

     # Provides a relative path to your source file(s). 
     src/main/cpp/src/com_myapp_system_Native.cpp 
     src/main/cpp/src/sha256.c 
     ) 

폴더를 포함시키는 방법을 모릅니다. src/main/cpp/src, src/main/cpp/src/*, src/main/cpp/src/*.cpp을 시도했지만 그 중 아무 것도 작동하지 않는 것 같습니다. 파일을 변경 한 후 내 응용 프로그램이 실행되기 시작하고 네이티브 구성 요소를 올바르게로드합니다.

+1

명시 적으로 이름으로 파일을 나열하는 것은 받아 들일 수 있으며 심지어는이를 처리하는 것이 좋습니다. 와일드 카드가 절실히 필요하다면 ['file (GLOB ...)'] (https://stackoverflow.com/a/3201211/192373)을 사용할 수 있습니다. –

+0

@AlexCohn 나는 "불이나 잊어라"라는 방식으로 폴더를 추가하는 것이 좋은 생각 일지 모르지만 실제로 CMake에 새로 온 것입니다. 그러나 명시 적으로 참조하는 것이 길 일 경우, 나는 이것을 이렇게 유지할 것이다. 코멘트 주셔서 감사합니다 :) –

0

안녕하세요, include_directory 대신 target_include_directories를 사용하십시오. 이 함수를 사용하여 디렉토리를 개인적으로 해당 라이브러리에 추가합니다. 그리고 여전히 원본 파일에 대한 오류가 발생하는 경우 소스 경로 줄에 {CMAKE_CURRENT_SOURCE_DIR}을 추가하십시오. 그것은 작동합니다!