ndk-build 명령어를 하면서 라이브러리파일이 생성이 안되거나, 생성이 되더라도 만들어진 앱을 실행 시 중지되었다


는 오류를 일으키는 문제에 대해 내가 찾아낸 해결법이다.


---------------------------------------------------------------------------------------------------------


1. 빌드 후에 프로젝트의 libs 폴더 내에 armeabi 폴더가 생성되어야 하고, 그 안에 so파일이 생성되어야 한다.



1.1 sequoyah 플러그인을 사용하지 않고 직접 커맨드창에서 ndk-build 명령을 수행하는 경우


이 경우에는 자신의 프로젝트 루트폴더까지 cd로 이동한 후에, ndk-build 명령을 수행한다.


--> ndk-build 실행 시




하지만 위의 사진과 같이 쉘에서 make를 처리하는데 무엇인가 신택스 에러가 발생했다는 문구가 나온다.


이 때에는 ndk-build 뒤에 -B SHELL=cmd 라는 옵션을 붙여 주자.


--> ndk-build -B SHELL=cmd 실행 시




성공. 이제 프로젝트의 libs->armeabi 폴더 내에 라이브러리 파일이 생성되었음을 확인할 수 있을 것이다.



1.2 sequoyah 플러그인을 사용하는 경우


sequoyah 플러그인은 NDK를 사용해서 JNI를 쓰는 경우 매번 명령행에서 ndk-build를 하지 않고도 빌드 시 자동으로


이러한 작업을 해주게 한다. 이외에도, 자동으로 jni파일과 그 안에 Android.mk파일과 c(혹은 cpp)파일을 생성해준다.


하지만 이 경우에도 일단은 ndk-build 명령을 프로젝트의 속성에서 명시를 해주어야 한다.


먼저 project -> properties -> c/c++ build의 build command에는 아래와 같이 build command가 작성되어 있다.


bash C:\android-ndk-r7c-windows\android-ndk-r7c\ndk-build


(path는 사람마다 다르겠지만, bash 프로그램으로 ndk-build를 실행한다는 것은 동일할 것이다. 아닐수도 있고.)


이상태에서 빌드를 해보면 콘솔창에 에러가 발생하지 않는다. 그런데, 문제는 라이브러리파일이 생성되지 않는다.


오류도 안뱉고 빌드가 성공적으로 처리된것 처럼 생각이 들어서, 라이브러리파일이 생성되지 않아도 되는줄 알았는


데 전혀 그렇지 않다. 이 경우에도 1.1번처럼 빌드를 하고나면 libs 폴더내에 armeabi폴더와 so파일이 생성되어야 한


다. 구글에 대략 검색을 해보니 윈도우즈 환경에서는 ndk-build가 아니라 ndk-build.cmd라고 커맨드에 적어주어야


한다고 한다. 거기다가 앞의 bash 프로그램은 사용하지 않는다.


C:\android-ndk-r7c-windows\android-ndk-r7c\ndk-build.cmd


이렇게 build command를 수정하고 다시 빌드를 해보자. 물론 위 path는 내 작업환경상에서 작성된거고, ndk-build


파일이 들어있는 ndk 폴더의 path를 명시해주어야 한다. 이렇게 설정한 후 빌드해보면,




다음과 같은 오류가 발생한다.


이 경우에도 1.1번과 마찬가지로 ndk-build.cmd 뒤에 -B SHELL=cmd를 덧붙여준다. 1.1번과의 차이점은 ndk-build


뒤에 .cmd가 붙었다는 것이다.(왜 그런지는 알 수 없다)


C:\android-ndk-r7c-windows\android-ndk-r7c\ndk-build.cmd -B SHELL=cmd


이렇게 build command를 다시 수정하고 빌드를 하면,




성공적으로 so파일이 만들어졌음을 알 수 있다. 이제 libs 폴더 내에 armeabi폴더와 so파일이 생성되었을 것이다.




이제 빌드를 하고 실행을 하면 되어야 하는 것이 정상적으로 예측할 수 있는 결과이다.



2. native method 구현부의 함수 네이밍과 관련된 문제


그런데 나의 경우, 앱을 실행할 때 자꾸 unfortunately has stopped~~ 라고 비정상적으로 종료했다는 에러메시지가


뜨는 것이었다. 처음에는 이러한 현상이 내가 만들어준 so파일을 앱에서 로드하지 못해서 so파일을 찾는 path에 문제


가 있는게 아닌가 싶었는데 그런 것이 아니었다. 문제는 바로 native method의 구현부를 작성하는 c(혹은 cpp)파일에


함수의 네이밍을 작성할 때 잘못된 path를 적었던 것이다..


native method의 구현부의 함수 네임을 줄 때에는 Java_패키지명_java파일명_함수이름


ex)

Java_com_example_jnitest3_MainActivity_stringFromJNI


이런식으로 작성해야 한다. java파일명에 native method를 선언하는 코드가 들어있는 java파일명을 적어야 하는지,


혹은 so파일을 로드하는 java파일명을 적어야 하는지 정확히는 모르지만 대게 한 파일내에서 이 두가지 코드가 모두


들어가기 때문에 크게 신경쓸 부분은 아닌 것 같다.


아무튼 나의 경우 JNI 샘플 코드들을 복붙하는 과정에서 함수 네임은 미처 수정하지 못하고 그대로 둔 상태였기 때


문에 에러가 발생했고, 에러가 무엇인지 약 4시간동안이나 삽질을 했던 것이다.


이러한 문제를 해결하고 나서, Hello JNI가 출력되는 것을 볼 수 있었다.



p.s) native method의 네이밍이 잘못되었으면, 빌드해서 라이브러리를 만드는 과정에서 오류가 발생해야 하는 것


아닌가? 라는 생각이 들었다. 함수 네이밍 문제가 런타임 때 발생될줄은..







Posted by huammmm1
,