출처: http://my.safaribooksonline.com/book/-/9781849691529/setting-up-your-environment/ch01lvl1sec05
나름번역해석: 202psj.tistory.com
처음 셋팅 Cygwin 필요하다.
Cygwin 설치는 아래 블로그들 설치 셜명에 자세히 있으니 보시고 설치해주세요,~!~!
Time for action — installing Android SDK and NDK on Windows
Cygwin 설치는 아래 블로그들 설치 셜명에 자세히 있으니 보시고 설치해주세요,~!~!
Open your Web browser and go to http://developer.android.com/sdk. This web page lists all available SDKs, one for each platform.
웹브라우저를 열어 http://developer.android.com/sdk.이동 웹페이지에서 sdk 를 받는다.
Download Android SDK for Windows, packaged as an Exe installer.
sdk를 설치한다.
Then, go to http://developer.android.com/sdk/ndk and download the Android NDK (not SDK!) for Windows, packaged as a ZIP archive this time.
http://developer.android.com/sdk/ndk 에서 ndk 를 받는다.
Execute Android SDK installer. Select an appropriate installation location (for example, C:\Android\android-sdk), knowing that Android SDK and NDK together can take more than 3 GB of disk space (currently!) with all official API versions installed. As a precaution, avoid leaving any space in the target installation path.
Follow the installation wizard until the end. Check the Start SDK Manager
sdk 설치시 모두 체크하여 설치
Check the Accept All option and click on Install to start the installation of Android components:
모두 수락하여 설치한다.
After a few minutes, all packages get downloaded and a message asking to restart ADB service (the Android Debug Bridge) appears. Validate by clicking on Yes.
Open the Environment Variables system window, as we did in the previous part. Inside the System variables list, insert the ANDROID_SDK and ANDROID_NDK variables with the corresponding directories as values.
윈도우 고급속성 - 환경 변수 - 시스템변수 에서 새로 만들기 ANDROID_SDK 변수이름, 값은 설치한
디렉토리, ANDROID_NDK 변수이름, 값은 설치한 디렉토리 각각 만든다.
자바(se) SDK 설치시에도 JAVA_HOME 아니면 JAVA_HOMEW 이런 이름 으로 환경 변수를 만들고 자바를 설치한 디렉토리를 값으로 예) C:\Program Files\Java\jdk1.7.0_09 이런씩으로 갑을 넣어주세요.
Append %ANDROID_SDK%\tools, %ANDROID_SDK%\platform-tools and %ANDROID_NDK%, all separated by a semicolon, to your PATH.
윈도우 고급속성 - 환경 변수 - 시스템변수 - path 에 위와 같이 설정을 해준다.
#android ndk,sdk 또는 ant, cygwin 설치시 중복되는 환경변수 이름으로 설정이 무효화나 에러가
#날수 있으니 꼼꼼히 살펴보고 성정해주어야 한다. (이름중복된다 생각할 경우 변수이름을
# ANDROID_SDKW, ANDROID_NDKW,JAVA_HOMEW <- 이런식으로 바꾸어주세요. 물론 PATH에 있는것도 같게 바꾸어주어야 겠죠~
Now, check the Ant version to make sure it is properly working on Cygwin:
$ ant -version
The first time Cygwin should emit a surprising warning: paths are in MS-DOS style and not POSIX. Indeed, Cygwin paths are emulated and should look similar to /cygdrive/<Drive letter>/<Path to your directory with forward slashes>. For example, if Ant is installed in c:\ant, then the path should be indicated as /cygdrive/c/ant.
Let’s fix this. Go to your Cygwin directory. There, you should find a directory named home/<your user name> containing a .bash_profile. Open it in edition.
At the end of the script, translate the Windows environment variables into Cygwin variables with the cygpath utility. PATH does not need to be translated as this essential variable is processed automatically by Cygwin. Make sure to use the prime character (`) (to execute a command inside another), which has a different meaning than the apostrophe (‘) (to define a variable) with Bash. An example.bash_profile is provided with this book:
#만약 ms-dos 스타일로 위 그림과 같은 문구가 나온다면 아래와 같이 설정을 해준다.
export ANT_HOME=`cygpath -u "$ANT_HOME"` export JAVA_HOME=`cygpath -u "$JAVA_HOME"` export ANDROID_SDK=`cygpath -u "$ANDROID_SDK"` export ANDROID_NDK=`cygpath -u "$ANDROID_NDK"`
# =' <- 여기부분은 띄움없이 바로 붙여서 써주어야한다. 띄움해도 되는부분과
# 안되는 부분이 있으니 신경써서 설정해주자.
#위 export는 자바 환경변수등록으로 설정한 값들이다. #하나라도 틀리면 인식이 안되니 조심하자 #ndk,ant,cygwin를 인스톨하면서 같은 환경변수이름으로 등록되는 경우도 있으니 #설정하는데 꼼꼼히 살펴보자.
#위와같이 설정을 하고나서
cd $ANDROID_SDK
cd $ANDROID_NDK
cd $ANT_HOME
cd $JAVA_HOME
을 해보아서 각각 디렉토리로 이동이 되면 설정이 적용된것이고 안되면 변수값이 중복되어 설정이 무효되거나 잘못 코드를 쓰여 인식이 안되는것이니 꼼꼼히 살펴보자.저는 이부분 때문에 설정이 안되어 골치 썩었습니다,꼼꼼히 보더니 중복 부분과 틀린 부분이 있더라구요.(202psj.tistory.com)
What just happened?
We have downloaded and deployed both Android SDK and NDK and made them available through command line using environment variables.
출처: http://www.androidpub.com/1172978
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
출처: http://viiiin.tistory.com/12
1. 개발환경
- Windows 7 Ultimate x86
Cygwin
- version 2.712
- http://www.cygwin.com
Eclipse
- Eclipse IDE for Java Developers : Galileo Packages(ver 3.5)
- http://www.eclipse.org/downloads
JDK
- Java SE Development Kit 6u21
- http://www.oracle.com/technetwork/java/javase/downloads/index.html
Android SDK & NDK
- Android SDK Package : android-sdk_r06-windows.zip
- Android NDK Package : android-ndk_r4b-windows.zip
- Android SDK and AVD Manager(Packages and Archives) : http://dl-ssl.google.com/android/eclipse
- http://developer.android.com/sdk/index.html
2. Cygwin 설치 및 환경설정
Cygwin을 사용하는 이유는 기본적으로 Android 개발 환경이 Linux 기반으로 되어 있기 때문이고, ndk-build 명령으로 빌드하기 위함입니다. 개인적으로 MinGW를 사용하시는 분은 MinGW에서 하셔도 좋습니다.
Cygwin 설치 시에 Select Packages 단계에서 'make'를 체크 후 설치해 줍니다.
저는 이미 설치되어 있기 때문에 'Keep'이라고 나오는 것입니다. 'Skip'부분을 클릭하면 'Install'로 바꿀 수 있습니다. 같은 방법으로 Search 기능을 이용하여 'vim'을 검색 후, Editors 카테고리의 vim을 'Install'로 바꾼 후 설치해 줍니다. 혹시 나중에 추가로 필요한 패키지가 생길 경우 다운받은 Cygwin 폴더의 setup.exe를 실행시켜 패키지를 추가할 수 있습니다.
다음으로 Cygwin을 실행하여 ndk-build 명령을 어디서든 실행할 수 있게 하기 위해 .bash_profile 파일의 PATH 환경변수에 경로를 추가시켜 줍니다.
/cygdrive 는 윈도우의 '내컴퓨터'와 같은 경로입니다. 저의 경우에는 다운받은 NDK 폴더가 아래의 경로에 있기 때문에 그림과 같이 PATH설정을 해 준 것입니다. 본인의 경로에 맞게 수정해주면 됩니다.
그럼 이제 cygwin은 모두 준비가 끝난 상태입니다.
3. Eclipse Android Project 생성
이제 Eclipse를 이용하여 안드로이드 프로젝트를 만들어 보도록 하겠습니다.
먼저, [File]->[New]->[Project]를 선택하면 다음과 같은 창이 나옵니다.
Android Project를 선택한 후, Next를 클릭합니다.
아래 그림과 같이 빈 곳을 채워준 다음 Finish를 클릭합니다. 이 때, 저는 "Use default location"을 체크해제한 후, cygwin의 홈디렉토리에 프로젝트 폴더를 만든 후 이곳의 경로를 지정해 주었습니다.
다음 그림과 같이 프로그래밍할 준비를 마쳤습니다.
4. 예제 프로그래밍
그럼 이제 본격적으로 안드로이드 App 예제를 실행하기 위한 프로그래밍을 해 보도록 하겠습니다.
① Activity Layout 구성
위치 : [HelloAndroid]-[res]-[layout]-[main.xml]
텍스트뷰와 버튼을 각각 하나씩 추가합니다.
//////////////////////////////////////////////////////////////////
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/callbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Call JNI"
/>
<TextView
android:id="@+id/rettxt"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="15pt"
/>
</LinearLayout>
//////////////////////////////////////////////////////////////////
② Activity 구현
위치 : [HelloAndroid]-[src]-[ssu.os.android]-[NdkTestActivity.java]
버튼 클릭으로 jni를 호출하는 소스를 onCreate에 구현하였습니다.
혹시 에러가 나거든 [Ctrl+Shift+O]를 이용해 자동으로 import를 수행해 줍니다.
///////////////////////////////////////////////////////////////////////////////
package ssu.os.android;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class NdkTestActivity extends Activity {
/** Called when the activity is first created. */
private Button bv;
private TextView tv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bv = (Button)findViewById(R.id.callbtn);
tv = (TextView)findViewById(R.id.rettxt);
bv.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
NativeCall nativeCall = new NativeCall();
int ret = nativeCall.add(10, 20);
String retStr = nativeCall.stringFromJNI();
Log.i("TAG", retStr + ret);
tv.setText(retStr);
}
});
}
}
///////////////////////////////////////////////////////////////////////////////
위치 : [HelloAndroid]-[src]-[ssu.os.android]-[NativeCall.java]
위의 위치에 NativeCall.java 파일을 새로 생성합니다.
native 함수가 들어있는 NativeCall 클래스를 생성합니다. native 키워드는 javah가 헤더파일을 생성할 때 참조하게 되는 키워드 입니다. 구현부는 없습니다. static 부분은 class의 객체가 생성될 때 (new) 되어질 때 호출됩니다. "my_lib"는 ndk-build로 생성된 라이브러리 이름입니다. 파일명은 libmy_lib.so 입니다.
④ javah 실행
~/bin 디렉토리에서 javah를 실행합니다. javah는 내부적으로 ./ssu/os/android/NativeCall.class 파일을 참고하여 헤더파일을 생성하게 됩니다. 헤더 파일명은 패키지명과 클래스명을 참고해서 생성됩니다. -o 옵션을 사용하면 파일명을 임의로 지정할 수 있습니다. 프로젝트 폴더에 /jni 폴더를 생성하고, 만들어진 헤더파일을 옮겨줍니다.
- 생성 된 헤더파일(ssu_os_android_NativeCall.h) 내용
native 키워드로 되어있던 함수들이 jni 형태 함수 프로토타입을 확인할 수 있습니다.
복잡해 보이지만 C문법입니다.
///////////////////////////////////////////////////////////////////////////////////
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class ssu_os_android_NativeCall */
#ifndef _Included_ssu_os_android_NativeCall
#define _Included_ssu_os_android_NativeCall
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: ssu_os_android_NativeCall
* Method: stringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_ssu_os_android_NativeCall_stringFromJNI
(JNIEnv *, jobject);
/*
* Class: ssu_os_android_NativeCall
* Method: add
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_ssu_os_android_NativeCall_add
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////////////////
⑤ 함수 구현
위치 : [HelloAndroid]-[jni]-[my_lib.c]
/jni 폴더에 my_lib.c 파일을 만들어서 다음과 같이 함수를 구현합니다. 두 개의 함수가 있는데 단순히 string을 리턴해 주는 함수와 두 정수를 입력받아 더한 후 리턴하는 함수입니다.
⑥ Android.mk 파일 작성
위치 : [HelloAndroid]-[jni]-[Android.mk]
다운받은 Android NDK 폴더의 /sample/hello-jni/jni 의 Android.mk 파일을 현재 프로젝트의 /jni 폴더에 복사한 후, 다음과 같이 수정하여 사용합니다. 수정 된 내용은 19, 20 라인의 LOCAL_MODULE 과 LOCAL_SRC_FILES 입니다.
⑦ NDK Build
프로젝트 루트 혹은 /jni 디렉토리에서 "ndk-build" 명령을 실행합니다.
빌드가 끝나면 프로젝트 폴더 밑에 /libs 폴더가 생성되고, 라이브러리인 .so 파일이 생성 된 것을 확인할 수 있습니다.
⑧ 에뮬레이터 실행
위의 과정이 정상적으로 진행되었으면 Eclipse에서 에뮬레이터를 실행시켜 줍니다. 안드로이드 부팅 과정이 끝나면 우리가 작성한 App을 볼 수 있을 것입니다.
Call JNI" 버튼을 누르게 되면 jni가 호출되어 스트링을 가져와 화면(TextView)에 뿌려주게 됩니다.
<참고 사이트>
[1] http://shchoi82.springnote.com/pages/6150375
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
최종 수정일 : 2011.02.18
남들보다 늦게 Android 를 시작하게 되네요...!
하지만, 늦더라도 천천히, 꼼꼼히 짚고 넘어가도록 하겠습니다.
현재 기본적으로 Android 가 설치가되어 있다고 생각 하겠습니다.
그리고 NDK 를 설치하기 위한 데이터를 알아보도록 할까요?
시작 해볼까요!? 작성하는데 얼마나 시간이 걸릴지^^;;
접기
# NDK 에서 제공되는 것들
- C/C++ 소스코드로 부터 네이티브 라이브러리를 생성하기 위한 각종 툴 및 빌드 파일
- 네이티브 라이브러리를 안드로이드 배포용 패키지 파일(apk)에 삽입하기 위한 방법
- 안드로이드 SDK(1.5버전 이후)를 지원하기 위한 시스템 헤더 및 라이브러리
- 문서, 샘플, 튜터리얼
#Cygwin
- Unix 계열 프로그램/유틸리티를, MS윈도에서 사용할 수 있도록 하는 커맨드 라인 인터페이스
- Cygwin을 Window에 설치하면 grep 이나 diff 등, 리눅스/유닉스의 명령어들을 사용할 수 있습니다.
(일부제외)
#Contents of the NDK
- libc(C Library) headers
- libm(math library) headers
- JNI interface headers
- libz(Zlib compression) headers
- liblog(Android logging) headers
- A Minimal set of headers for C++ support
#. 필요한 재료를 모아봅시다! ( 2011.02.18 version)
#Cywin 설치
Cywin 설치 과정입니다. 간단한 설명으로 마무리 짓고 넘어 가도록 하겠습니다.
Android 특강을 들었던 내용의 일부와 제가 직접한 스크린샷 입니다 @@
Reference [*] S5PC100기반 안드로이드 포팅 및 응용프로그램 개발(주) 휴인스
접기
위의 사이트에서 다운을 하시기 바랍니다. (파일도 같이 첨부해드립니다. 포스팅을 보는 사람들을 위해서, 혹시나 시간이 많이 지나서 포스팅을 보시게 된다면, 링크를 따라서 다운을 받아주시기 바랍니다.)
# 설치를 시작합니다.
# Install form Internet 선택
# Cygwin 이 설치될 경로 선택!
# 패키지가 다운될 경로 지정(용량이 많으니, 2G정도~? 적절한 하드디스크로...)
# Direct Connection 선택
# Kaist 가 가장 속도가 빠르다고 하네요..(ftp://ftp.kaist.ac.kr ) 을 선택하도록 합니다.
# 필수항목 선택 devel(gcc-core, gcc=g++, make, vim(맞던가..) ) 를 선택 하면 됩니다.
귀차니즘으로 인해 Devel 을 클릭해서 전부 설치를 하였네요..^^;;
# 뒷부분은 생략하도록 하겠습니다. 설치 프로세스와 마지막 확인 누르는 화면인데 미리 캡쳐를 해두지 못했네요..^^
# 환경설정
위쪽의 환경변수에 새로만들기 를 하여 추가를 하도록 합니다.
아래의 그림처럼
변수이름 : HOME
변수 값 : /home/(사용자이름)
# 설치가 되고 [시작]-[프로그램]-[Cygwin]-[Cygwin Bash Shell] 을 실행합니다.
# 처음 실행할 때는 바로 떳는데 ... 어느센가 살포시 검은창이 조금 오래 있네요..
# 아래의 그림처럼 뜬다면 설치가 성공한 것입니다.
만약 문제가 있다면 다시 따라서 해보시기 바랍니다. 그리고 Cygwin 을 설치하는 과정에서 패키지를 다운받다가 끊키는 경우가 많은데...모든 패키지를 다 받지 마시고 필요한 Devel 만 받기를 권합니다. 받는데도 시간이 30~1시간 가량 걸리더군요... 기다리면서 포스팅이 시작이 되어버렸죠 하하...
# 이상 Cygwin 설치과정은 여기서 종료가 되겟습니다. 그리고 다음 과정을 보도록 합시다.
접기
# Android NDK 설치
이번에는 Android NDK 를 설치하도록 해보겠습니다. 아래의 설명대로 따라와 주신다면 어려운 것은 별로 없습니다. 글자보다. 이미지를 많이 첨부하도록 할터이니, 부디 아까운 시간을 버리지 말고 천천히 따라와 주시기 바랍니다.
접기
android-ndk-r5b-windows.zip(60M 가량 됩니다. 파일 첨부는 안할께요, 링크도 편하니ㅋ)
# URL 로 들어가셔서 아래 Windows Package 를 다운 받도록 합니다.
# 압축풀기
다운 받은 파일을 Cygwin/home/(사용자계정) 아래에 다음과 같이 풀도록 합니다.
# cygwin/home/(사용자계정)/.bashrc 파일 수정
파일을 메모장으로 열면 깨지게 됩니다. 수정을 하실 때에는 Editplus, Eclipse, Visual Stuido 를 열어서 수정을 하면 보기에도 편합니다.
# 내용 추가
제일 마지막 Line 에 아래의 내용을 추가 하도록 합니다.
export ANDROID_NDK_ROOT=/home/(사용자 계정)/(패키지 마다 버전이 틀리니 폴더확인!)
# 이렇게 하면! Android NDK 가 설치가 끝이 납니다.
접기
- 아무래도 책 2권의 NDK 를 보고, 구글에서 검색된 포스팅인데...의외로 꼼꼼히 정리가 잘되어 있었습니다. 하지만 처음 보는 저한테 이미지가 부족한 ㅜ_ㅜ 조금더 제가 꼼꼼히 작성해보리라 ...합니다.
[2] S5PC100기반 안드로이드 포팅 및 응용프로그램 개발(주) 휴인스
- 특강을 들었던 (주) 휴인스 강사님의 얇지만 탄탄한 내용의 자료를 참조하여서 작성하였습니다.
셋팅을 정리하고나니, 먼가 많이 부족한 느낌이 드네요...전 셋팅할 때 뭔가...엄청 복잡했거든요...
이번강좌를 이렇게 줄이고, 예제를 따라 해보도록 하겠습니다.
NDK 를 설치하고나면 Sample 폴더 아래에 많은 예제가 있습니다.
그 예제들이.................!? 강좌가 많이 있더라구요..그래서 전 책에 있는 계산기 예제를 해보려고 합니다.
그럼 다음 포스팅에서 뵙겠습니다.
by 퓨림노
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
최종 수정일 : 2011.11.07
- cygwin 에서 ndk-build 명령어를 수행하기 위한 방법(전 몰랐습니다 ㅜㅜ)
이렇게 쉬운거였다니 -_-;; ( 젤아래 포스팅 합니다)
최종 수정일 : 2011. 02. 18
이번에는 분량이 많은데...
포스팅의 순서가.
1. 후르륵 정리 -> 2. 세부적인 정리(포스팅은 따로) -> 3. 후르륵정리에 링크걸기 를 하려고합니다.
블로그에 이렇게 들어오나 저렇게 들어오나...? 뭐 어짜피 하나라는 것.
정리는 꼼꼼히 하도록 하겠습니다. 이유는... 도서관에서 빌린 책이라서...도로 돌려줘야하니깐...
책은 다시 사기에 돈이~아깝구 그래서 몽땅 정리 해볼까 합니다 .하하하..
이번 NDK 예제를 책에서 따라하고, 인터넷에서 따라하고 엄청난 삽질을 하였네요...
그만큼 이번포스팅은 꼭 제대로 정리하고 만다라고 각오하고 포스팅을 합니다.
이제 따라 가볼까요?
접기
# 결과의 보시는 것과 같이 간단한 게산기 입니다.
아! 디자인 말씀이시군요!? 하루종일 NDK 관련된 설명만 보느라..미쳐 디자인에는 신경을 못썻네요..
뭐 그것보다 중요한건 한번 해보는게 아닐까요^^;;; (말돌리기)
NDK 를 사용하지 않고 계산기를 만든다고하면 뭐 만들 수 있죠, 하지만 이게 C/C++ 을 사용하기위한 발단이 될수도 잇는 것이죠.
그리고 시작을 하면서 포기하는 사람은 포스팅을 닫아주시기 바랍니다.
적어도...꼼꼼히 설명할 것을! 약속합니다.
# NDK 예제의 전체적인 순서를 알아 볼까요?
하루종일 따라해보았는데 그래도 저두 해깔리는데..(누가 제욕하던가요..귀가 갑자기 간지럽네요^^;;)
긴소리 안하고 정리 하겠습니다. (수다 떠는걸 여기서 다떠네요....)
아래 글을 적고보니 9단계의 절차가 나오네요...
[포스팅 Reference http://micropilot.tistory.com/1522]
1. Android Project 작성
2. 자바 클래스 작성
3. Header 파일 작성
4. 라이브러리 생성할 소스 디렉토리 생성
5. Android.mk 설정 파일 생성
6. C 소스파일 작성
7. 소스 컴파일/공유라이브러리 생성
8. Native 메소드 호출
9. 결과 확인
에효, 한숨 쉬면서 시작 해볼까요? 절차라 머저리 긴지...정리하는 저두 부담이 되네요 ㅎ
아 그냥 포스팅,,,하면서 프로젝트 하나 다시 만들어 볼께요 =ㅅ=!! 최대한 이미지를 많이 쓰기위해서죠.
1. Android Project 작성
@ 주의사항
안드로이드를 D:\android\worksapce 의 경로로 저장을 하였습니다. 하지만 Cygwin 폴더로 있는 곳으로 한번 이동을 해야합니다. 그이유는 Build 를 하기위해서, java header 파일을 만들기 위해서죠.
하지만, 다른 방법도 있다는 사실, Cygwin 의 Path 경로를 옮겨오는 것도 하나의 방법 이니깐요..
설명하는 지금은 Export/Import 를 이용하여서 Cygwin/jppark(사용자계정)/(project) 로 옮겨왔습니다. Export/Import 하는 방법이 궁금하시다면 ->__(포스팅을 다시하겠죠? ㅎㅎ)
# New Android project
Project name : NDKclac
Build Target : Android 2.1-update1
Application name : Hello! NDK!
Package name : com.tistory.studyandroid
Create Activity : NDKcalc
Min SDK version : 7
2. 자바 클래스 작성
(설명을 위해서 주관적으로 말을 합니다. 틀린 부분이 있다면 지적 부탁드립니다. 단지! 이게 필요하다는 설명을 위해서...주절주절 쓰고있습니다^^;;)
- 엥~!? 왜 작성하냐구요? 지금 이 포스팅을 보고 계신분은 NDK 라는 것을 이용하여 C/C++ 코드를 사용하기 위함이 아니시던가요? 그럼 필요한게 무엇인가요!? header 파일이 필요하지 않나요?
NDK 에서 C/C++ 의 Header 파일을 만들기 위해서는 먼저 Java 를 이용하여 헤더파일을 작성하고나서
javah 명령을 통하여 JNI에 사용되는 header 파일을 생성하도록 합니다 .
3. Header 파일 작성
(이미지로 해둬어서 찝찝하시죠? 복사 붙여 넣기도 못하고? ㅎㅎ 그래서 아래 ..준비했습니다
package com.tistory.studyandroid;
public class calc {
public native int add(int x, int y);
public native int mul(int x, int y);
public native int div( int x, int y);
static
{
System.loadLibrary("calc"); // libcalc.so 파일을 로드함
}
}
#main.xml File
디자인은 별로지만, 위와같은 형태로 구성을 하기위해서 xml 을 작성합니다. 설명하지 않아도 작성을 충분히 할 수 있을 꺼라 생각됩니다. 물론 저도 Android 를 본지 3일째인가요!? NDK 가 그냥 필요해서 보고 정리하는거라,,,앞에 내용은 후르륵~ 라면 먹듯이 보고 넘어왔네요 ,,, 새벽 4시를 달리며,,,라면 먹고 싶네요 =ㅅ=
소스코드를 첨부합니다
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:textSize="20sp"
/>
<!-- First Layout -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<EditText
android:id="@+id/value1"
android:layout_width="50sp"
android:layout_height="wrap_content"
android:text="5"
></EditText>
<TextView
android:id="@+id/display"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+"
android:textSize="20sp"
></TextView>
<EditText
android:id="@+id/value2"
android:layout_width="50sp"
android:layout_height="wrap_content"
android:text="6"
android:textSize="20sp"
></EditText>
<Button
android:layout_height="wrap_content"
android:text="="
android:layout_width="50sp"
android:id="@+id/btnCalc"></Button>
<TextView
android:id="@+id/Result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:text="Result"
android:textSize="20sp"
></TextView>
</LinearLayout>
<!-- second Layout -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+"
></Button>
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="*"
></Button>
<Button
android:id="@+id/btn3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="/"
></Button>
</LinearLayout>
</LinearLayout>
접기
# 이제 Build 를 하기 위한 과정으로 넘어가 볼까요?
4. 라이브러리 생성할 소스 디렉토리 생성
# jni 폴더는 자동으로 생성이 되지 않으므로 수동으로 생성을 해주어야 합니다.
방법은 탐색기 폴더에서 생성하는 것과 아래 프로젝트에서 생성을 할 수 있습니다.
# jni 라고 폴더이름을 적어준다.
# 이제 jni 폴더에 이제 Android.mk 파일을 생성하도록 합니다.
5. Android.mk 설정 파일 생성
# Android.mk File 작성
접기
include $(CLEAR_VARS)
LOCAL_MODULE := calc
LOCAL_SRC_FILES := calc.c
include $(BUILD_SHARED_LIBRARY)
이제 설명이 필요하겟죠? (참조[2])
# LOCAL_PATH := $(call my-dir)
- 컴파일하고자하는 소스 파일의 위치를 언급
- $(call my-dir) 은 "my-dir"라고 불리우는 매크로 함수를 호출(call)하는 것을 의미
- 결과적으로 LOCAL_PATH 에는 "<프로젝트 폴더>/jni" 가 할당될 것
# include $(CLEAR_VARS)
- CELAR_VARS 변수는 "clear-vars.mk" 로 선언되어 있음
- "include $(CLEAR_VARS)" 라는 의미는 "clear-vars.mk" make 파일을 여기 Android.mk 파일에 포함하라는 의미가 됨
-
-
# LOCAL_MODULE := calc
- Android.mk 파일 내 최종 생성되는 모듈을 위해 선언되어야 할 변수
- calc 라고 정하면 최종 결과물은 "/libs" 디렉터리 내에 "libcalc.so" 라이브러리 생성
# LOCAL_SRC_FILES := calc.c
- 모듈을 제작하는데 사용하는 C와 C++ 의 소스 파일들을 가르킴
- 만약 라인을 띄어서 다수의 파일명을 입력한다면 아래와 같이 사용가능
toto/bar.c
# include $(BUILD_SHARED_LIBRARY)
- 생성되는 라이브러리는 공유라이브러리로 제작한다는 의미
- 정적 라이브러리로 하고 싶다면
$(BUILD_STATIC_LIBRARY)
$(LOCAL_STATIC_WHOLE_LIBRARIES)
(but, 안드로이드에서 제공하는 NDK에서는 정적 라이브러리 제작에 필요한 파일들이 빠져있어 정상적인 방법으로는 정적 라이브러리를 생성시킬 수 없음)
접기
6. C 소스파일 작성
C 파일도 새롭게 작성을 하기위해서 파일을 추가합니다. 아무래도 그림이 빠져있으면??? 도대체 어디서 해야하는지 영문을 모르는 분들을 위해서 한장 첨부합니다. (물론 저도 그랬으니깐요 ㅎㅎㅎ)
# 소스 코드 작성
소스 코드를 긁어 볼까요? ( 어디 간지러우신가..맨날 긁어가시게...?)a
더보기
#include <jni.h>JNIEXPORT jint JNICALL Java_com_tistory_studyandroid_calc_add
( JNIEnv *env, jobject obj, jint value1, jint value2 )
{
return (value1+value2);
};
JNIEXPORT jint JNICALL Java_com_tistory_studyandroid_calc_mul
( JNIEnv *env, jobject obj, jint value1, jint value2 )
{
return (value1*value2);
};
JNIEXPORT jint JNICALL Java_com_tistory_studyandroid_calc_div
( JNIEnv *env, jobject obj, jint value1, jint value2 )
{
if(value2)
return (value1/value2);
return 0;
};
7. 소스 컴파일/공유라이브러리 생성
그럼
1. calc.java 파일을 가지고 calc.h 파일을 생성
2. libcalc.so 파일을 생성하기 위한 build
위의 2가지 과정이 남아있군요... 곧 끝나가네요! 휴휴... 새벽 4시... 네트워크 까지 다보고 잘꺼라서..!!
먼저 그림을 보시면 알겠지만
# 현재 경로 확인
(Cygwin/jppark(사용자계정)/Project(생성한프로젝트) 를 Export 해서 넣어두세요)
# 현재 경로를 이동
$cd bin
# javah 명령을 통한 header 파일 생성
# 생성된 Header 파일 확인!
중요한게 아니라 접어둡니다. 간지러우신분은 더보기 클릭!!
왜 간지러우신 분이라고 했는지 이제 이해하시죠? ㅎㅎ 이해가 안되었다면 꼼꼼히 안보셨다는거?
@ 참 파일명이 [패키치]_[클래스이름].h 로 나오게 되어 길게 됩니다.
@ 그래서 [클래스이름].h 로 줄여줍니다.
더보기
# 이제 libcalc.so 파일을 생성하기위해서 Bulid 하는 과정을 볼까요!?
# 당연히 그림의 순서대로 가시면 됩니다.
# 현재 경로 확인
# Build 명령 내리기
Build 명령어에 대해서 조금 더 알아 볼까요?
@신규 빌드 작업 : ndk-build
@신규 빌드 및 빌드 명령어 출력 : ndk-build V=1
@이전 바이너리 파일 삭제 : ndk-build clean
@강제 리빌드 작업 : ndk-build -B
@강제 리빌드 및 명령어 출력 : ndk-build -B V=1
@빌드 작업과 NDK 로그 메시지 출력 : ndk-build NDK_LOG=1
@Build 되어 생성된 so 파일 확인
생성되는 파일! 중요하지만 간지러우신 분들만 확인 바랍니다. ㅎㅎㅎ
더보기
8. Native 메소드 호출
본문의 소스내용을 작성합니다. Native 가 사용된 곳에 표시를 해두겠습니다.
더보기
9. 결과 확인
휴...드디어 결과를 보는군요...!!! 행복합니다.
# 아아앗!? 그런데 왜 에러인가요!?
물론 블로그에 있는 내용을 긁어다가 사용하신 분들이라면 될려나? 좀 많이 간지럽죠. 이렇게 글을 계속 읽고 있다는 것은,,,안된다는 뜻이 아닐까 싶기도 한데(앗! 그냥 혼잣말이에요, 기분나빠하지 마시길^^;;)
에효..에러가 떳으니 왜 떳는지..알아봐야하겠죠?
그나저나...저 포스팅을 하는 지금.. 하루만에 찾기는 했지만, 도통 NDK 의 구조가 갈피도 잡히지도 않고, 인터넷에 아무리 검색해봐도 되지도 않고,, 그렇다고 인터넷에 따라해도 되지도 않고...그러더군요...
현재 포스팅을 하는 초기에도 몰랐습니다. 물론 제가 스스로 간지러워서 젤처음에 이야기한 프로젝트를 제가 직접 만들면서 캡처를 한다고 이야기를 하였는데.. 지금의 에러가 어디서 나는지 찾기 위해서 이런 삽질을 하고 있습니다. 60억 인구중에 누군가가 똑같은 에러를 만날테고...같은 생각을 하고 있을테니깐요...
같은 생각을 하는 이유는 같은 행동을 하고 같은 것을 바라보고 같은 것을 먹고...등등...
그러하니깐요...아무도 나와 같은 생각을 할 수 없게 하려면 ?... 어떻게 해야할까요?
무념무상..?? <-- 꼬숙이(후배)가 말하는 저말이..정답일지...갑자기 생각나서 주절주절....
그만큼 -_-..지금 일어난 에러에 대해서...한이 좀 맺혀있나보네요...
참...정확하지는 않지만 에러는 금방 잡았습니다. 이유가 이유라면 잘못적은 오타 라고 보시면되죠..
확인 해볼까요?
etc. 에러난 이유를 알아보자.
천천히 하나씩 살펴 보았습니다. 삽질을 하는 지금까지, 똑같은 프로젝트를 몇번이나 만들어 보았을까요?
#calc.java File 입니다.
@: ㅡㅡ^ 아래의 그림을 보시면, 생성된 library 파일은 libcalc.so 입니다.
@ 즉, NDKcalc 라는 파일이름은 이미 현재 파일 추가가 되어있는 Zip 내의 내용입니다(과거의 내용).
이러한 상황이 왜 발생했냐? 책이랑 인터넷이랑 보고 여러번 프로젝트 만들면서 복사/붙여넣기를 하면서 수정하지 않은 탓이지요...(물론 제잘 못입니다. 누구나가 처음에 범하는 실수죠...)
@ 그렇다면...누군가가 좀 명시를 해줘야 하지 않나? 이건 주의사항으로 좀 알려 달란!! 이런 말입니다.
그래서...
1. Header 파일을 생성하기위한 calc.java 파일과 생성되는 lib(header name).so 파일명은 일치해야한다.
설명이 부족하네요...
Header 파일을 생성하기 위한 java header 에 사용된 이름과, 빌드를 통하여 생성된 so 파일의 이름은 아래와 같아 야 한다는 공식입니다.
HeaderName = libHeaderName.so
# 간결하지 못한 느낌인데... 더 적었다간 해깔릴 것이라 생각 되어 이만 작성합니다.
# java header 파일을 다시 생성 함
java header 파일을 수정하였으므로 다시 생성하도록 합니다.
# 에러가 발생한 곳이 하나 더 잇었네요..^^;;
현재 본 포스팅의 5번째 C소스 파일 작성을 보면 아래 그림에 붉은색으로 밑줄 그어져 있는 부분과 다르다는 것을 알게 될 것입니다.완전 초보적인 실.수. 네요... 당연히 전 안드로이드를...보는 3일 초짜입니다. 물론...개발자로서는 오래 있었을지도 모르지만요..(비참하군요..이런 실수를 한다는게..)
# 프로젝트 ReBuild 하기
C 소스 코드를 수정하였으므로 so 파일을 다시 생성을 해야겠죠?
아래의 그림과 같이 다시 빌드를 합니다.
휴..드디어 끝이났다. 이제 결과를 보도록 할까요?
디자인은 별로지만! 끝을 제대로 확인하지 않으셨던가요!?
결과를 보셨으니 행복하시죠!?
그리고..전 새벽 5시가 되어서 포스팅이 끝이 나네요...
아직 포스팅이 끝났다고는 말못합니다.
NDK 에 대한 빠진 내용을 책을 참조해서 다시 계속 정리를 할 것이니깐요...
그럼 계속...열심 히! 포스팅 하는 것 기대해 주시기 바랍니다.(헐...3시간 걸렸네..ㅜㅜ)
2011.11.07
cygwin 에서 ndk-build 명령어 수행을 위한 방법
방법은 간단합니다.(....)ㅠ
시스템 환경 변수 PATH 에 NDK 경로를 추가해 주면 됩니다.
exmaple 을 보셔야 이해 하시겠죠?
(현재 위에랑 setting 을 바꾸었습니다. )
.bashrc 파일에서
export ANDROID_NDK_ROOT=/home/android-ndk-r6b 경로 수정
(실제 C:\cygwin\home\android-ndk-r6b 입니다.)
그리고 시스템 [내컴퓨터]-[환경변수]-[PATH] 란에
C:\cygwin\home\android-ndk-r6b 를 넣어줍니다.
아아 그림이 없으니 내가 알아보기도 힘들겠다....
그리고 .bashrc 파일에
export PATH=$PATH:/home/jppark/android-ndk-r5b (이전 버전) 이렇게 추가하면 되는거 같은데
안되나보네..ㅡ.ㅡ.... 파일에서 path 거는 방법 아시는분 댓글 좀 부탁들비니다^^
이상~!!
- 아무래도 책 2권의 NDK 를 보고, 구글에서 검색된 포스팅인데...의외로 꼼꼼히 정리가 잘되어 있었습니다. 하지만 처음 보는 저한테 이미지가 부족한 ㅜ_ㅜ 조금더 제가 꼼꼼히 작성해보리라 ...합니다.
[2] 전문가로 가는 안드로이드 마스터 프로젝트 (주) 교학사
- 도서관에서 NDK 가 있어서 빌린 책입니다. 가지고 있는 안드로이드 책 한권으로 부족함을 느끼고, 인터넷을 찾아보면서 하는 것도 한계가 있기 때문에 도서관을 찾아나섰습니다. 책을 빌려놓고 한달간 보지도 않았네요..그리고 특강을 듣기 시작하면서 보게 되었는데...물론 필요한 부분만^^;; 그래도 그냥 버린게 아니라서 다행이네요..
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
출처: http://blog.naver.com/jbin_k?Redirect=Log&logNo=130119612989
Android에서 C/C++(native code)를 이용하면 좋겠다는 생각(물론 시켜서;;)을 하고 나서
여기저기 알아보다 보니 Android에서 NDK를 이용하면 된다는 글을 봤다.
처음 접하는 내용이지만 뭐 그냥 대충하면 되겠지란 생각으로 덤볐다...피봤다ㅋ
그럼 현재 가장 최신의 버전에 맞추어 차근차근 해보자. 결코 어렵지 않다.
(현재 나와있는 포스팅들 따라하면 무슨 값이 나와야 하는데 절대 나오지 않아 삽질만....)
내가 겪은 문제점들 모두 글로 설명하겠어요. 세부사항까지 한 번 써보겠습니다.
그럼 먼저 간단한 용어부터 알아보자.
*NDK
쉽게 말해, native code(C/C++)를 사용하기 위한 툴
*Cygwin
윈도우 시스템에서 Linux와 비슷한 환경을 만들어주는 프로그램
*JNI (Java Native Interface)
자바와 C/C++모듈 간의 인터페이스를 가능하게 해주는 것
그럼 설치를 해보자
1. Cygwin (http://www.cygwin.com/)
중간 부분에 Current Cygwin DLL version 밑에 setup.exe를 클릭 후 실행
현재 다른 포스팅들을 보면 여기서 daum 이나 kaist를 찾아서 다음을 누르라고 나온다
옆의 스크롤 막대 보이는가? 글씨도 작다. 찾으면 나 좀 알려줘요ㅠ
찾지마시고 default로 되어 있는 사이트에서 받으시면 됩니다.
저는 이미 설치를 한 상태라 다른 분 사이트에서 사진 한장만 집어왔습니다.
Devel 에서 gcc/gcc++, make~ 이런거 찾아서 받아도 되지만 난 시크하니까 Devel 통째로 받겠습니다. 여기서 다음을 누르면 시간이 좀 소요 되오니 막간을 이용해 허리한번 피시고 거북이 목 집어 넣으시기 바랍니다.
(제 경험상 99%에 컴퓨터가 누운적이 한번 있었는데 울면서 다시 했습니다. 처음보단 빠릅디다.)
여기까지하시면 설치가 완료 되었고 다음으로 환경변수를 조정하셔야 합니다.
내컴퓨터 -> 마우스우클릭 -> 속성 -> 고급 -> 환경변수 클릭 (참 친절합니다.)
시스템변수 안에 Path클릭 후 편집 버튼(위에 사용자 변수 아니고 아래 시스템변수 입니다. 확인요망.)
; C:\cygwin\bin ; C:\cygwin\usr\include
제일 앞에 ; 붙여 주시고 저랑 똑같이 하셨다면 위의 내용을 붙여넣기 하시고 다르시면 bin 폴더와 include 폴더를 추가해주시면 되겠습니다.
이제 프로그램 실행 한번 해보겠습니다.
시작 -> 프로그램 -> Cygwin -> Cygwin Bash Shell 클릭
아 잘 됩니다. Cygwin 설치 끗~!
2. Android NDK 설치 (http://developer.android.com/sdk/ndk/index.html )
우린 Windows 기반이니까 윈도우로 받음
자신이 원하는 적절한 위치에 받아 둔다.
(현재 버전은 android-ndk-r6b 입니다. 과거 포스팅은 버전이 천차 만별이더군요)
압축을 풀어야 하는 위치는 따로 지정해야 함
반드시 Cygwin 폴더 안에 home/(사용자 명) 요 안에다 푸셔야 합니다.
저 같은 경우는 C:\cygwin\home\jbinK 이렇게 되겠군요
다음으로
cygwin/home/(사용자계정)/.bashrc 파일 수정
(여기서도 흔히 메모장으로 열려고들 하시는데 낭패봅니다.ㅋ)
(eclipse / Visual Studio / Editplus 로 여시면 됩니다. 가끔 연결할줄 모르시는 분들이 계시는데 그럴땐 다 필요없습니다. 프로그램 켜놓고 드래그 하심이 가장 빠를듯 하옵니다.)
제일 마지막 줄에
export ANDROID_NDK_ROOT=/home/jbinK/android-ndk-r6b
export ANDROID_NDK_ROOT=/home/(사용자 계정)/(패키지 마다 버전이 틀리니 폴더확인!)
여기까지하면 설치가 완료된 것이다.
이 다음은 간단하게 Hello JNI 프로젝트를 실행해보고
그 다음으로 직접 간단한 프로젝트를 제작해 보는 시간을 갖도록 하겠습니다.
일하면서 캡쳐까지 하려니 일이 두 배가 되어 정신이 하나도 없네요ㅠ
이거 한다고 월급을 더 주는것도 아닌데ㅠㅠ
////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
출처: http://blog.naver.com/brighteyes79?Redirect=Log&logNo=130081136539
안드로이드 JNI 를 개발하기 위해서는 환경 세팅부터 차근 차근해야하더군요.
우선 기본적으로 앞에 포스팅한 SDK 2.1 설치부터 하고, 물론 이미 하신 분들은 패쓰.. ^^;;;;
1. NDK 다운로드
가벼운 마음으로 NDK를 다운로드받아서 zip을 풀어주고 SDK와 마찬가지로 마음에 드는 폴더 위치를 잡아줍니다.
2. Cygwin 설치
http://www.cygwin.com/ 에 들어가면 Install or update now! 라고
써있는 다운로드 링크가 있습니다. 왠만하면 exe 파일을 저장한 후 실행하여 설치하라고 하더군요.
설치에 있어 중요한 것은 인터넷으로 다운받아가면서 설치하되,
install directory 와 package directory를 적당한 위치에 잡아주고,
Direct Connection 으로 받되 다운로드 사이트는 뭘 선택해도 중간에 끊어지는 일이 자주 있으니 운에 맞기게 되더라는 것이죠.
그리고 패키지 선택하는 화면에서 devel 에서는 gcc (core, c++) 와 make 를 반드시 선택하여 설치를 시작하면 됩니다.
물론 설치는 차암 오래 오래 걸립니다. ㅠㅠ
3. Cygwin Bash Shell 실행
시작->프로그램->Cygwin 에 보면 Cygwin Bash Shell 이 있습니다.
이걸 실행시키면 shell 화면이 뜹니다. (아마도 바탕화면의 sygwin 아이콘이 있다면 그걸 실행시켜도 되죵)
실행시키면 cygwin 홈 디렉토리에 가 있기 때문에 우리가 ndk 에서 사용하기가 불편합니다.
그러면 다음과 같이 하면 된다고 하네요.
202psj 첨부
아래그림 cydrive 이후 부터 자기가 설치한 ndk 위치를 android_ndk 띄움 전까지 적어야한다.
그리고 \ <- / 로 바꾸어주고 아래 형식 비슷하게 형을 바꾸어주어야 한다.
그러면 cd android_ndk 라고만 치면 원하는 ndk 폴더로 훌쩍 이동합니다.
shell 이라고 해서 저처럼 멀미하지 말고 그냥 dos 려니 하고 dir, cd 뭐 이런 명령어를 자유롭게 사용하시면 됩니다.. (난 왜 몇년에 한번씩 cygwin 만 보면 과민 반응을,, )
4. setup shell 을 실행하여 NDK 설치
NDK 라고 마무리는 shell 로 설치합니다.
android_ndk 라고 명명한 ndk 폴더로 가서 아래와 같이 치면 설치가 됩니다.
"Host setup Complete" 라고 뜨면 끝.
5. Sample 어플인 Hello-jni 를 컴파일
NDK를 모두 설치하였으니 백문이 불여일타 라고, make 명령어를 이용하여 컴파일을 해볼까요?
단번에 말로만 듣던 so 라이브러리가 만들어졌습니다.
6. 이클립스에서 실행.
이클립스에서 New로 프로젝트를 하나 만드는데, 존재하는 소스로 만들기로 들어가서(영어로 뭐였죠? 응?? ㅋㅋ) apps\hello-jni 폴더를 선택합니다. 다음 그림을 보면 굼방 이해되실 듯.
그리고 실행하면 끝,, 엄휘나 너무 간단하쟎아???
설마 이걸 보고 안드로이드 JNI 개발이라는 건 아니겠지??
아.. 그게 아니구..
이제 환경이 세팅되었으니 제대로 개발하는 법을 정리해보자구요.
다음 포스트를 보시면 이제 시작하시는 겁니당... GoGo
////////////////////////////////////////////////////////////////////////////////////////////////////
출처: http://cozyhouse.tistory.com/44
안드로이드 NDK r4로 "프로 안드로이드 게임 개발" 예제 빌드하기저번 달(2010년 5월)에 NDK r4가 나왔습니다.
http://developer.android.com/sdk/ndk/index.html
주목할만한 변화는 ndk-build라는 빌드 명령이 추가된 것인데요. 이제는 NDK 루트 이외의 디렉터리에서, 특히 개별 프로젝트 디렉터리 자체에서 네이티브 코드를 빌드할 수 있게 되었습니다.
프로 안드로이드 게임 개발의 예제들을 NDK r4로 빌드하는 방법을 간단하게만 정리해 보겠습니다.
우선 해야 할 일: 제5장 OpenGL 예제의 cuberenderer.c에 오류가 하나 있는데 ndk 1.6이나 r3에서는 그냥 경고로 넘어갔지만 r4에서는 오류로 간주되어서 컴파일이 실패합니다.
jni/cuberenderer.c 의 24행
- #include <EGL/egl.h>
을 삭제하거나 다음처럼 주석으로 처리하면 됩니다.
- //#include <EGL/egl.h>
기존 make APP= 방법을 그대로 사용
r4에 ndk-build라는 새 명령이 도입되긴 했지만 기존의 make APP= 도 여전히 작동합니다. 유일한 차이는 NDK r4의 루트 디렉터리(이하 <ndk-r4> 디렉터리)에 apps라는 디렉터리가 미리 만들어져 있지 않다는 것 뿐입니다.
<ndk-r4> 디렉터리에 apps라는 하위 디렉터리를 직접 만든 후 부록 A와 B에 나온 절차를 그대로 적용하면 됩니다. 부록 A와 B를 이미 따라한 독자라면 NDK r3의 apps 디렉터리를 그냥 통채로 <ndk-r4>에 복사해도 되겠고요.
새로운 ndk-build 사용
(이 글 끝의 "ndk-build에 대해 좀 더"를 먼저 읽으셔도 좋습니다.)
부록 A, B를 아직 따라하지 않은 독자라면 make APP= 를 실행하기 직전 단계까지 따라하세요. apps 폴더에 프로젝트를 복사할 필요는 없습니다.
그리고 Cygwin에서 nkd-build 명령을 어디에서나 실행할 수 있게 설정해 두어야 합니다(export PATH= 등)
이제 Cygwin 셸에서 프로젝트 디렉터리(보통의 경우 AndroidManifest.xml 파일과 jni 하위 디렉터리가 있는 디렉터리)로 가서 그냥
- $ ndk-build
를 실행하면 됩니다.
다음처럼 특정 디렉터리를 직접 지정하는 것도 가능합니다.
- $ ndk-build -C $WORKSPACE/wolf3d
ndk-build에 대해 좀 더
ndk-build는 현재 디렉터리(또는 -C 옵션으로 지정된 디렉터리)에서 AndroidManifest.xml를 찾습니다. 그 파일이 있으면 현재 디렉터리를 유효한 안드로이드 프로젝트 디렉터리라고 간주하고, 그 디렉터리의 jni 디렉터리로 들어가서 거기에 있는 Android.mk에 의거해서 빌드를 진행합니다(GNU make로). 그것 뿐입니다.
위의 과정에서 보듯이, r3까지 쓰이던 Application.mk는 이제 필요가 없습니다. 물론 NDK 루트에서 make APP= 를 실행하는 방식을 사용하려면 여전히 Application.mk가(그리고 apps 디렉터리가) 필요합니다.
이 정도만 알면 코드의 실질적인 오류, 즉 컴파일 오류나 링크 오류 이전의 사소한 문제점들은 충분히 해결할 수 있을 것입니다.
위 링크로 가시면 문자열 값을 출력하는 것 까지 자세한 정보가 있습니다.
그대로 따라하시면 되는데요.
사이사이에 제가 겪은 문제점들을 적어 놀까 합니다.
1. ../ndk-build 명령어를 쳤더니
위와 같은 에러가 났을 경우.
혹시, android ndk 가 Program files 밑이나 띄어쓰기가 있는 이름 폴더의 하위 폴더 일 경우 인지 확인해보세요.
절대! cygwin 설치에 문제가 아닙니다.
가장 안전한 방법!
c:\android-ndk-xxxx로 해놓으시는게 가장 좋을 듯!
2. cygwin 설치 시, ftp://ftp.kaist.ac.kr이 안보일 경우
그냥 아무거나 하셔도 됩니다. 한국 사이트라 다운로드 속도가 빠른 것 뿐! ㅋ
3. .so파일까지 만들어지고 실행을 했는데!!!
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): java.lang.UnsatisfiedLinkError: getMsgFromJni
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at com.motiveflux.ndk.hello.NdkHello.getMsgFromJni(Native Method)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at com.motiveflux.ndk.hello.NdkHelloActivity.onCreate(NdkHelloActivity.java:18)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at android.os.Handler.dispatchMessage(Handler.java:99)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at android.os.Looper.loop(Looper.java:123)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at android.app.ActivityThread.main(ActivityThread.java:3683)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at java.lang.reflect.Method.invokeNative(Native Method)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at java.lang.reflect.Method.invoke(Method.java:507)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-11 15:57:23.210: ERROR/AndroidRuntime(4166): at dalvik.system.NativeStart.main(Native Method)
package : android.test.ndk.hello
NdkHello.c 파일 :
jstring Java_android_test_ndk_hello_NdkHello_getMsgFromJni(JNIEnv *env, jobject thiz)
NdkHello.h 파일 :
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := HelloLibrary
LOCAL_SRC_FILES := NdkHello.c
include $(BUILD_SHARED_LIBRARY)
그럼 제 경험담을 써 놓았습니다.
좋은 참고사항이 됐으면 좋겠습니다.^^