IT_Programming/Android_NDK

[Android Studio] Android Studio Project에 NDK 적용하기

JJun ™ 2015. 5. 19. 03:02

 [출처]
 : 
https://www.davidlab.net/ko/tech/using-the-android-ndk-with-android-studio-part1/

 : https://www.davidlab.net/ko/tech/using-the-android-ndk-with-android-studio-part2/#more-1429


 

 

NDK는 C/C++과 같은 Native Code를 위한 언어를 이용하여 Android App의 일부분을 구현할 수 있도록 도와주는 Toolset 입니다.

이것을 이용하면 개발자는 기존에 Embedded Linux에서 개발하던 방식과 유사하게 C/C++로 구현하여
Toolset 으로 Build 한 Native Library 를 Java의 JNI를 이용하여 Java Code내에서 사용할 수 있게 됩니다.

 

기존의 Eclipse 기반의 ADT를 이용하는 경우에는 Eclipse의 CDT Plugin을 이용하여 IDE Level의 NDK 지원이 가능했지만,
Android Studio의 경우에는 C/C++ Compile 및 Debugging을 제대로 지원하지 않기 때문에 NDK를 적용하는데 어려움이 있습니다.

 

이번 Post에서는 Android Studio에서 생성한 Project에 NDK로 Build한 Library를 사용하는 방법과
Build System에 통합하여 Build하는 방법 및 Debugging하는 방법에 대해서 알아보도록 하겠습니다.

 

 

1. NDK 설치

먼저, Android Studio와 Android SDK가 System에 설치되어야 있어야 합니다. Ubuntu의 경우에는 이 Post를 참고하여 설치하면 됩니다.

설치가 완료되었다면, System에 Android NDK를 설치하기 위해서 Android Developers에서 NDK를 Download합니다.

그리고 다음과 같이 입력하여 NDK를 설치합니다.

 

 

 * Ubuntu의 경우:

 

    $ chmod 755 android-ndk*.bin
    $ ./android-ndk*.bin -o$HOME

    $ vi ~/.bashrc


      export ANDROID_NDK_HOME=$HOME/android-ndk-r10d
      export PATH=$PATH:$ANDROID_NDK_HOME


    $ source ~/.bashrc

 

 


 

 

 * Mac OS X의 경우:

 

   $ mkdir -p $HOME/Library/Android
   $ chmod 755 android-ndk*.bin
   $ ./android-ndk*.bin -o$HOME/Library/Android
   $ vi ~/.bash_profile

 

      export ANDROID_NDK_HOME=$HOME/Library/Android/android-ndk-r10d
      export PATH=$PATH:$ANDROID_NDK_HOME

 

   $ source ~/.bash_profile

 

 

 

2. Project에 NDK 적용

이번 항목에서는 설치된 NDK를 Android Studio Project에서 사용하도록 설정하는 방법에 대해서 예제와 함께 설명합니다.

이번 항목은 이해를 위하여 Step-by-Step으로 따라할 수 있도록 작성되었습니다.

2.1 Project 생성

 

 

먼저, 새로운 Project를 생성합니다.
Create New Project Dialog에서 위와 같이 App Name에 NDKTest라고 입력하고 Domain은 상황에 맞게 입력한 후 Next를 누릅니다
.

 

 

Target Devices는 Default로 두고 Next를 누릅니다.

 

 

Activity 선택에서는 Blank Activity를 선택하고 Next를 누릅니다.

 

 

Activity 설정에서는 Default로 두고 Finish를 눌러 Project 생성을 완료합니다.

 

 

2.2 Source Code 수정

이제 생성된 Project의 Source를 수정해 봅시다. res/layout/activity_main.xml을 열어서 기본적으로 추가되어 있는 TextView를 다음과 같이 수정합니다.

 

 

<TextView
        android:id="@+id/textView"
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

 

 

 

public class MainActivity extends ActionBarActivity {

  static {

    System.loadLibrary("NDKTest");

  } 

 

  public native String getStringFromNative();

 

  @Override

  protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

 

    // TextView에 Native Method를 호출한 결과를 표시한다.

    TextView view = (TextView) findViewById(R.id.textView);

    view.setText(getStringFromNative());

  }

}

 

 

 

위의 Code를 간단히 설명하면 다음과 같습니다.

  • Line 2-4: NDK로 Build한 Native Library를 Load합니다. Argument로는 Library File Name에서 확장자를 뺀 것을 입력합니다. (NDKTest.so ?? NDKTest)
  • Line 6: Native Library에서 구현한 Method의 Interface를 native keyword로 선언합니다. 이렇게 선언된 Method는 실제로 구현되어 있지 않아도 Build가 가능합니다.
  • Line 14-15: Activity 생성 시에 Layout에 정의된 TextView에 Native Method를 호출한 결과를 출력하는 Code입니다.

Source를 모두 수정했다면, Build > Make Project를 눌러 Source를 Build합니다.

2.3 JNI Code 생성

NDK는 Native Code 구현을 위해 Java의 JNI(Java Native Interface)를 사용합니다.

간단하게 말하면, NDK는 Java에서 지원하는 Native Code 호출 규약인 JNI를 이용해서 Native Code를 App에서 사용할 수 있도록 도와줍니다.

떄문에 Java Source에서 선언한 Native Method를 구현하기 위해서는 JNI를 위한 C/C++ Header를 생성하고,
생성된 Header에 선언된 Native Method에 해당하는 Interface를 C/C++ Code로 구현하면 됩니다.

먼저 Android Studio의 Terminal(Alt + F12)을 열고, Build된 Java Class를 이용하여 Header를 생성하기 위해서 다음과 같이 입력합니다.

 

$ cd app/src/main
$ mkdir jni
$ javah -d jni -classpath $ANDROID_HOME/platforms/android-22/android.jar:$ANDROID_HOME/extras/android/support/v7/appcompat/libs/android-support-v7-appcompat.jar:$ANDROID_HOME/extras/android/support/v7/appcompat/libs/android-support-v4.jar:../../build/intermediates/classes/debug net.davidlab.ndktest.MainActivity 

 

 

javah 명령에서 유의할 것은 app/build.gradle에 정의되어 있는 targetSdkVersion에 맞는 경로를 -classpath에 추가해 주어야 합니다.
위의 경우는 API 22(Android 5.1)를 사용할 경우의 예입니다.

그리고 javah의 마지막 인자에 Package Name을 포함한 MainActivity class의 Full Name을 적어야 합니다.

 

생성이 제대로 되었다면 위의 그림과 같이 PROJECT_HOME/app/src/main/jni/fully_qualified_class_name.h가 생성됩니다.

이제 생성된 Header를 이용하여 Native Code를 구현해야 합니다.
PROJECT_HOME/app/src/main/jni/main.cpp를 생성하고 다음과 같이 입력하고 저장합니다.

 

#include "net_davidlab_ndktest_MainActivity.h"

JNIEXPORT jstring JNICALL Java_net_davidlab_ndktest_MainActivity_getStringFromNative(JNIEnv *env, jobject obj)
{
  return env->NewStringUTF("Hello from JNI!");

 

 

위의 구현은 다음과 같은 구조로 되어 있습니다.

  • Line 1: javah로 생성된 Header를 Include합니다. Header 이름은 상황에 맞게 변경해야 합니다.
  • Line 3: 생성된 Header에서 MainActivity.java에서 선언한 getStringFromNative()에 해당하는 Interface의 Prototype을 그대로 복사하여 입력하고 인자에 변수명을 추가합니다.
  • Line 4: 실제 구현내용입니다. String을 생성하여 Return합니다.
JNI 구현에 대한 자세한 내용은 이 Post에서 다루지 않습니다. 좀 더 자세한 내용은 Oracle의 JNI Specification에서 확인할 수 있습니다.

 

2.4 Android.mk 생성

Native Code까지 구현이 완료되었다면, Library로 Build하기 위해 Android.mk를 생성해야 합니다.

NDK에서는 Native Code의 Build를 위해서 GNU Make를 사용합니다.
Android.mk는 Make를 위한 Makefile 형식으로 된 Build 설정 File로 Native Library를 Build할 때 사용됩니다.

PROJECT_HOME/app/src/main/jni/Android.mk를 생성하고 다음과 같이 입력합니다.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)


LOCAL_MODULE    := NDKTest

LOCAL_SRC_FILES := main.cpp

LOCAL_LDLIBS := -llog


include $(BUILD_SHARED_LIBRARY) 

 

 

위의 내용을 간단히 설명하면 다음과 같습니다.

  • Line 5: LOCAL_MODULE에는 생성될 Library의 이름을 입력합니다. 위에서는 MainActivity.java에서 loadLibrary()의 인자로 입력하였던 Library 이름인 NDKTest가 사용되었습니다.
  • Line 6: LOCAL_SRC_FILES에는 Build할 Source File을 입력합니다. 여러 개일 경우 Space로 구분하여 입력하면 됩니다. 위의 내용에서는 이전에 생성한 main.cpp를 Source로 지정하였습니다.
  • Line 7: LOCAL_LDLIBS Library Link 시에 사용하는 ld 명령을 위한 Option을 지정합니다. 위의 경우는 Android의 Logcat을 사용하기 위한 Option이 추가되어 있습니다.
자세한 Android.mk의 사용법은 ANDROID_NDK_HOME/docs에 위치한 Documentation에서 확인할 수 있습니다.

 

2.5 Application.mk 생성

Application.mk도 Android.mk와 마찬가지로 Native Library Build 시에 필요한 File로, Build 시에 Android App과 관련된 설정을 지정할 수 있습니다.

PROJECT_HOME/app/src/main/jni/Application.mk를 생성하고 다음과 같이 입력합니다.

 

  APP_ABI=all

 

 

위의 내용에서는 APP_ABI 변수에 Native Library Build를 위해 Target ABI(Application Binary Interface)를 설정합니다.

ABI는 Binary Level의 호환 Interface를 의미합니다. 이것은 CPU Type에 의존하며, NDK는 armeabi, x86, mips 등의 ABI를 지원합니다.

위와 같이 all로 입력할 경우 Android가 지원하는 모든 ABI를 위한 Native Library를 Build하게 됩니다.

자세한 Application.mk의 사용법은 ANDROID_NDK_HOME/docs에 위치한 Documentation에서 확인할 수 있습니다.

 

2.6 Gradle 설정

NDK를 위한 Code를 모두 작성했으니 이제 Gradle Build System을 수정할 차례입니다.



먼저 그에 앞서, Gradle에서 NDK에 포함된 명령들을 사용하기 위해서 System에 설치된 NDK의 경로를 입력해야 합니다.

File > Project Structure > SDK Location에서 Android NDK location에 System에 설치된 NDK의 경로를 입력합니다.

NDK의 경로는 PROJECT_HOME/local.properties에 저장됩니다.


혹은 그냥 (위 UI를 통한 방법을 따르지 않고)  Build System에서 NDK가 설치된 경로와 Debugging이 가능하도록
Library를 Build할 지 여부를 확인할 수 있도록 
다음과 같이 PROJECT_HOME/local.properties를 수정합니다.

 

 ndk.dir=/home/davidhyk/android-ndk-r10d

 ndk.debug=false 

 

ndk.dir에는 실제 NDK 설치 경로를 입력해야 합니다.


그리고 Android Studio 1.3 이상의 경우, Android Gradle Plugin에서 새로 지원하는 실험적인 NDK 지원 대신에
이전 Version 에서 사용하던 방식을 사용하도록 설정해야 합니다.


설정을 위해서 gradle.properties에 다음과 같은 내용을 추가합니다.

 android.useDeprecatedNdk=true


 

그 다음에는 App을 Build할 때 NDK를 이용하여 Native Library도 같이 Build할 수 있도록 build.gradle을 수정해야 합니다.

PROJECT_HOME/app/build.gradle에 다음과 같은 내용을 추가합니다.

 

 


import org.apache.tools.ant.taskdefs.condition.Os

// Project Structure에서 설정한 NDK 경로를 읽어들여 Return합니다.
def getNdkBuildPath() {
  Properties properties = new Properties()
  properties.load(project.rootProject.file('local.properties').newDataInputStream())

  def command =  properties.getProperty('ndk.dir')
  if (Os.isFamily(Os.FAMILY_WINDOWS)) {
    command += "\\ndk-build.cmd"
  } else {
    command += "/ndk-build"
  }

  return command
}

android {
  sourceSets.main {
    // Compile된 Native Library가 위치하는 경로를 설정합니다. 
    jniLibs.srcDir 'src/main/libs'
    
    // 여기에 JNI Source 경로를 설정하면 Android Studio에서 기본적으로 지원하는 Native
    // Library Build가 이루어집니다. 이 경우에 Android.mk와 Application.mk를
    // 자동으로 생성하기 때문에 편리하지만, 세부 설정이 어렵기 때문에 JNI Source의
    // 경로를 지정하지 않습니다.
    jni.srcDirs = []
  }
  
  ext {
    // 아직은 Task 내에서 Build Type을 구분할 방법이 없기 때문에 이 Property를
    // 이용해 Native Library를 Debugging 가능하도록 Build할 지 결정합니다.
    nativeDebuggable = false
  }

  // NDK의 ndk-build 명령을 이용하여 Native Library를 Build하기 위한 Task를 정의합니다.
  //noinspection GroovyAssignabilityCheck
  task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
    if (nativeDebuggable) {
      commandLine getNdkBuildPath(), 'NDK_DEBUG=1', '-C', file('src/main').absolutePath
    } else {
      commandLine getNdkBuildPath(), '-C', file('src/main').absolutePath
    }
  }
  
  // App의 Java Code를 Compile할 때 buildNative Task를 실행하여 Native Library도 같이 Build 되도록 설정합니다.
  tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn buildNative
  }  

  // NDK로 생성된 Native Library와 Object를 삭제하기 위한 Task를 정의합니다.
  //noinspection GroovyAssignabilityCheck
  task cleanNative(type: Exec, description: 'Clean native objs and lib') {
    commandLine getNdkBuildPath(), '-C', file('src/main').absolutePath, 'clean'
  }

  // Gradle의 clean Task를 실행할 떄, cleanNative Task를 실행하도록 설정합니다.
  clean.dependsOn 'cleanNative'
  
  buildTypes {
    debug {
      // Debug Build시에 Native Library Debugging이 가능한 APK를 생성하도록 설정합니다.
      jniDebuggable true
    }
  }
}

 

 

위의 내용을 간단히 설명하면 다음과 같습니다.

  • Line 4: jniLibs.srcDir에 Compile된 Native Library가 위치하는 경로를 설정합니다. 위와 같은 설정의 경우 ndk-build 명령을 이용한 결과물이 app/src/main에 위치하므로, build.gradle이 위치한 app Directory의 경로를 제외한 src/main/libs가 설정되었습니다.
  • Line 5: jni.srcDirs에 경로를 설정하면 Android Studio에서 기본적으로 지원하는 Native Library Build가 이루어집니다. 이 경우에 Android.mk와 Application.mk를 자동으로 생성하기 때문에 편리할 수는 있으나, 세부 설정이 어렵기 때문에 여기서는 JNI Source의 경로를 지정하지 않습니다.
  • Line 8-27: NDK의 ndk-build 명령을 이용하여 Native Library를 Build하기 위한 Task를 정의합니다. local.properties에 정의된 ndk.dir, ndk.debug Property의 정보를 이용하여 Library를 Build합니다.
  • Line 28-30: App의 Java Code를 Compile할 때 ndkBuild Task를 실행하여 Native Library도 같이 Build되도록 설정합니다.
  • Line 31-35: Debug Build시에 Native Library Debugging이 가능한 APK를 생성하도록 설정합니다.

build.gradle을 수정했다면 Sync Now를 눌러 동기화합니다.

 

 

2.7 Project Build 및 Test

이제 모든 작업이 끝났습니다. Android Studio에서 Run > Run을 실행하여 Project를 Build하고 Emulator 또는 Device에서 실행하여 Test합니다.

 

Native Library가 Build되었는지 확인하려면 위의 그림과 같이 Gradle Console Tool Window에 ndkBuild Task가 실행되었는 지 확인하면 됩니다.

 

 

App을 실행하면 위와 같이 TextView에 JNI Code에서 Return한 Text가 표시되는 것을 확인할 수 있습니다.

 

 

3. 마치면서…

이상으로 System에 NDK를 설치하고 Android Studio에서 NDK를 이용하여 Native Library를 Build하고 Java Source에서 사용하는 방법을 알아보았습니다.

이어지는 Part2에서는 Android Studio에서 Native Library와 Java Code를 같이 Debugging하는 방법과 몇 가지 Tip을 공유하도록 하겠습니다.

Tested Environments

  • Ubuntu 14.10: oracle-java7-installer-7u72, android-studio-1.1.0, android-ndk-r10d
  • Mac OS X 10.10: Xcode Command Line Tools 6.0, Oracle JDK 1.7.0, Android Studio 1.1.0, Android NDK Revision 10d

Image Sources

References

 

 



[External Tool 설정으로 빌드하기]


 - ndk-clean은 파라메터에 'clean'만 추가하면 된다. (참조: http://blog.daum.net/creazier/15310192)







 

 


 

 

 

 

 

Part 1에 이어서 이번 Post에서는 NDK가 적용된 Project를 Debugging하는 방법을 알아보고, NDK와 관련된 몇 가지 Tip들을 소개하도록 하겠습니다.

 

 

4. Debugging

Eclipse에서 CDT를 이용하여 Native Library를 Debugging할 경우에는 특별한 설정이 없어도 IDE 차원에서
편리하게 Debugging이 가능하지만, Android Studio에서는 C/C++ Debugging을 지원하지 않기 때문에 약간의 과정이 필요합니다.

이번 항목에서는 Native Library를 위한 Debugging 설정과 App Debugging 시에 Java Code와 Native Code를 같이 Debugging하는 방법에 대해서
알아보도록 하겠습니다.

4.1 local.properties 수정

Native Library의 Debugging을 위해서는 Build 시에 Debugging이 가능하도록 Build해야 합니다.

이전 Post의 build.gradle에서 ndkBuild Task를 보면, Debug Build인지 확인하기 위해서 ndk.debug Property를 사용하는 것을 확인할 수 있습니다.

아래와 같이 local.properties의 ndk.debug를 true로 설정하여 Native Library의 Debugging이 가능하도록 설정합니다.

 

ndk.debug=true 

 

아직까지는 Gradle Task 내에서 Build Type을 구분하는 방법이 없기 때문에, Debug Build 상태를 얻기 위하여
ndk.debug라는 Property를 임의로 지정하여 사용합니다.

 

 

4.2 Build Variant 설정

 

 

 

Build Variant는 일반적으로 사용하는 Build Type과 거의 동일한 개념으로 Build Flavor + Build Type으로 이루어져 있습니다.

build.gradle에서 특별한 Flavor를 지정하지 않았기 때문에 Build Variant에는 debug, release와 같은 Build Type만 표시될 것입니다.

Debugging이 가능한 Build 결과물을 얻기 위해서는 위의 그림과 같이 Build Variants Tool Windows에서 Build Variant를 debug로 설정합니다.

설정 후에 Build > Make Project를 실행하여 Project를 Build합니다.

 

4.3 Java Code와 함께 Debugging하기

 

 

 

이제 Debugging을 위한 준비가 끝났습니다. 먼저 위의 그림과 같이 MainActivity의 onCreate()에서 setText()를 호출하는 Line에 Breakpoint를 설정합시다.

그리고 Debugging을 시작하기 위해서 Run > Debug를 실행하고 Emulator나 Device에서 Debugging을 시작합니다.

App이 실행되면 Breakpoint가 활성화됩니다. 여기까지는 일반 Java Code Debugging가 다를 것이 없습니다.

이제 Native Library Debugging을 위해 Android Studio의 Terminal(Alt + F12)에서 다음과 같이 입력하여 Native Library를 위한 Debugger를 실행합니다.

 

 

$ cd app/src/main
 $ ndk-gdb 

 

 

 

ndk-gdb 명령이 실행되면 위의 그림과 같이 GDB 명령행이 표시되고 App Debugging의 제어권이 GDB로 넘어가게 됩니다.

GDB는 Unix-like OS에 사용되는 Debugger로 명령행에서 Debugging을 위한 명령을 입력하여 사용합니다.

list를 입력하면 Debugging을 위한 Native Code가 표시됩니다.

여기서 break 4를 입력하면 Native Code의 4번째 행(NewStringUTF()를 호출하는 부분)에 Breakpoint를 설정하게 됩니다.

Breakpoint를 원하는 곳에 설정한 다음에는 cont를 입력하여 App Debugging이 계속 진행되도록 설정합니다.

 

 

이제 App Debugging의 제어권은 Android Studio로 돌아왔습니다.

현재 Breakpoint가 설정된 행의 다음으로 진행하기 위해서 Android Studio의 Editor를 Mouse로 Click한 다음, Run > Step over를 누르면 위의 그림과 같이 다른 Debugger의 명령이 끝날 때까지 기다리는 상태로 돌입하게 됩니다. (Native Library의 getStringFromNative()가 호출되면서 gdb로 설정한 Breakpoint가 활성화되었기 때문)

 

 

Debugging의 제어권이 GDB로 넘어오면 위의 그림과 같이 Breakpoint가 활성화 되었다는 Message와 함께 명령행에서 GDB 명령을 실행할 수 있게 됩니다.

여기서 print명령을 이용하여 변수의 값을 확인하는 등의 여러가지 Debugging 명령을 이용하여 Debugging합니다.

그리고 다시 Debugging의 제어권을 Android Studio로 넘기려면 cont를 입력합니다.

 

 

제어권이 Android Studio로 돌아오면 위의 그림과 같이 Breakpoint의 다음행으로 Program Counter가 이동했다는 것을 확인할 수 있습니다.

이와 같이 Android Studio의 Debug 기능과 ndk-gdb를 사용하면 Java Code와 Native Library를 동시에 Debugging을 할 수 있습니다.
약간은 복잡한 방법이지만 익숙해지면 쉽게 따라할 수 있을 것입니다.

자세한 GDB의 사용법은 GNU Korea의 GDB를 이용한 디버깅 문서를 참고하기 바랍니다.

 

 

 

5. Tips

이번 항목에서는 Android Studio에서 NDK를 사용하는데 도움이 될 만한 몇 가지 Tip들을 소개합니다.

 

 

5.1 Native Library만 Debugging하는 방법

App의 Java Code와는 별개로 Native Library만을 독립적으로 Debugging하려면 다음과 같이 Android Studio의 Terminal에서 입력합니다.

 

 

 $ cd app/src/main
 $ ndk-gdb --start --nowait 

 

 

위의 명령을 사용하기 전에 Test할 Emulator나 Device에 Debug Build의 App이 먼저 설치되어 있어야 합니다.

그리고 당연한 이야기이겠지만, Debugging을 통해 Native Code만을 수정했을 경우에는
Gradle Tool Window에서 installDebug Task를 실행하는 것을 잊지 마시기 바랍니다.

 

 

5.2 CGDB를 이용하여 Debugging하는 방법

NDK로 Build한 Native Library의 Debugger로 사용되는 GDB는 뛰어나지만 명령행에서 명령을 입력해서 사용해야 하므로 조금 불편한 면이 있습니다.

GDB의 Front-end인 CGDB는 IDE의 Debugger와 유사하게 Source 확인과 Breakpoint 사용 및 단축키 사용등이 가능하고 동시에
GDB 명령행도 사용할 수 있어서 좀 더 편리하게 Debugging을 할 수 있도록 도와줍니다.

NDK로 Build한 Native Library를 Debugging할 때 CGDB를 사용1하기 위해서는 먼저 다음과 같이 입력하여 System에 CGDB를 설치합니다.

 

 

     * Ubuntu의 경우:  

        $ sudo apt-get install cgdb

 

     * Mac OS X의 경우(설치를 위해 Homebrew가 필요):

       $ brew install cgdb

 

 

CGDB를 설치했다면 NDK에서의 사용을 위해 다음과 같이 입력하여 새로운 실행 Script를 생성합니다.

 

 

 [create-ndk-cgdb.sh ]

 $ cp $ANDROID_NDK_HOME/ndk-gdb $ANDROID_NDK_HOME/ndk-cgdb
 $ vi $ANDROID_NDK_HOME/ndk-cgdb

 

 [ndk-cgdb.sh]

 #GDBCLIENT=${TOOLCHAIN_PREFIX}gdb
 GDBCLIENT="cgdb -d ${TOOLCHAIN_PREFIX}gdb --"

 

 

마지막으로, ndk-gdb를 이용해 Debugging하는 것과 마찬가지로 Debugging 시점에 다음과 같이 Terminal에서 ndk-cgdb를 실행합니다.

 

 

 [ndk-cgdb.sh]

 $ cd app/src/main
 $ ndk-cgdb 

 

 

 

 

CGDB가 실행되면 gdb를 사용할 때와 마찬가지로 먼저 Breakpoint를 설정해야 합니다.

ESC Key를 눌러 CGDB mode로 들어간 다음, 위 또는 아래 화살표를 이용하여 행을 지정하고 Space bar를 눌러 Breakpoint를 지정합니다.

그리고 F6를 눌러 Continue를 실행하면 Native Library를 위한 Debugging 준비가 끝나게 됩니다.

i Key를 누르면 GDB 명령행에서 GDB 명령을 사용할 수 있으며, ESC를 누르고 :q를 입력하면 CGDB가 종료됩니다.

자세한 CGDB의 사용법은 CGDB Manual을 참고하기 바랍니다.

 

5.3 Project를 Git으로 관리할 경우 Ignore 설정

NDK가 적용된 Android Studio Project에 Git이 VCS로 적용되어 있다면, PROJECT_HOME/app/.gitignore에 다음과 같이 입력하여
Compile된 결과물들이 Repo에 추가되지 않도록 설정하는 것이 좋습니다.

 

 

 /src/main/libs
 /src/main/obj

 

 

 

 

6. Source Code

Part 1과 2에서 사용한 Sample Project를 GitHub에 올려두었습니다. Clone에서 사용하는 방법은 다음과 같습니다.

     

        1. Repository를 Clone합니다.

            $ git clone https://github.com/davidhyk/ndktest.git

 

        2. Android Studio의 File > Import Project에서 Clone한 Directory를 선택합니다.
        3. local.properties를 수정합니다.

 

           ndk.dir=<NDK 설치 경로>
           ndk.debug=false


        4. Run > Run을 실행하여 App을 Build하고 실행합니다.

 

 

Tested Environments

  • Ubuntu 14.10: oracle-java7-installer-7u72, android-studio-1.1.0, android-ndk-r10d
  • Mac OS X 10.10: Xcode Command Line Tools 6.0, Oracle JDK 1.7.0, Android Studio 1.1.0, Android NDK Revision 10d

Image Sources

References