오늘 외부에서 일해야 하는 상황이 생겨서, 데스크탑에서 잘 빌드가 되던 소스를 통째로 랩탑에 복사해 왔었다.


그리고 NDK 빌드를 하는데 NEON을 사용할 때 필요한 cpufeatures라는 NDK에 기본적으로 포함된 소스를 찾지 못하는 문제가 발생했다.


NDK가 데스크탑에는 D드라이브에, 랩탑은 C드라이브에 설치되어 있었는데, 랩탑에서 계속 NDK path를 D에서 찾는 것이었다.


뭐가 문제인지 몰라 NDK에 포함된 기본 mk 파일들에서 사용하는 NDK_ROOT 변수는 정상적인 C드라이브의 경로로 설정이 되어 있었다. 정말 귀신이 곡할 노릇!!!


그러다 찾아낸 문제는 바로 NDK 빌드를 하면서 obj 디렉토리에 생성되는 .d 파일이었다.


파일 확장자로보아 dependency를 기록해 두는 파일인 것 같은데, cpufeatures에 대해 데스크탑에서 생성된 .d 파일이 남아 있어 계속 D드라이브에서 해당 소스를 찾았던 것이었다.


obj 디렉토리를 삭제하고 다시 빌드하니 잘 되었다. 아놔, 이것 땜에 허비한 시간을 생각하면.


Sigh.

(마침 John Carmack이 문제가 있는 USB 케이블 때문에 시간을 허비했다는 트윗에서 이렇게 한숨을 쉬던 기억이 나서 따라해봄ㅋㅋㅋ)

Posted by 세월의돌

Google code에 android-ndk-profiler가 있고, 설명도 잘 되어 있다.

그런데, 나의 이해력이 부족해서 그런건지 모르겠지만, 애매하게 잘 안되었던 부분들이 있어서 정리한다.

 

 


 

설명에는 다운로드한 압축파일을 $HOME/tools 위치에 해제하고, ndk-build에 NDK_MODULE_PATH를 이용해 경로를 지정하라고 되어 있는데, 나의 경우에는 NEON 사용을 위해 cpufeatures를 추가로 사용하기 때문에 그런건지, 아니면 Windows 환경이라서 그런 것인지는 모르겠지만 빌드 에러가 발생했다.

 

이 문제는 그냥, 아래와 같이 ANDROID NDK가 설치된 경로에 복사해서 해결했다.

 

android-ndk-r9d\sources\android-ndk-profiler

 

 


 

 

그리고 arm-linux-androideabi-grpof를 실행할 때 profiling 한 library를 넘겨주라고 되어 있는데,

 

$ANDROID_NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gprof your_lib.so

 

stripped library라고 에러메시지를 뱉어 냈다.

 

평소에는 Eclipse에서 libs/armeabi-v7a/에 생성된 .so 파일만 바라보았기 때문에, 다른 위치에 또 생성이 되는지는 몰랐다.

찾아보니 lib/armeabi-v7a/에 생성되는 .so 파일은 stripped library 이며, 여기에서 필요한 non-stripped library는 obj/local/armeabi-v7a/에 생성된다.

 

알고보니 내가 설명을 자세히 읽지 않았었군...;;

 

Run the gprof tool, passing it the non-stripped library (usually in $PROJECT/obj/local/armeabi-v7a/libXXXX.so or $PROJECT/obj/local/armeabi/libXXXX.so). This is for NDK version r5b onwards, in earlier versions the path to gprof is different but should still work.

 

 


 

 

위의 obj/local/armeabi-v7a/에 생성된 .so 파일을 넘겨주면 결과가 stdout으로 출력되니, 파일로 redirection하여 출력하면 보기 편하다.

 

Posted by 세월의돌
리눅스 & 안드로이드2014. 6. 30. 20:02

무엇보다 설정이 중요하므로 화면만 캡쳐 해 둔다.

 

(아래 그림) Eclipse에 NDK path를 설정하는 기능이 있다! 처음 알았네...;;

심지어는 Project에 NDK를 지원하도록 자동으로 설정하는 context menu도 있다-0- (이건 screenshot 누락됨^^;)

 

 

 

 

(아래 그림) NDK_DEBUG 옵션은 말 그대로 옵션임. 기본은 Use default build command checkbox가 선택되어 있다.


 

 

 

 

(아래 그림) 자체적으로 설명이 된다. self descriptive screenshot? ; )


 

 

 

 

(아래 그림) 이것도 자체적으로 설명이 된다. self descriptive screenshot? ; )


 

Posted by 세월의돌

OpenSL ES를 사용하기위해 NDK로 빌드를 하고 있는데, 컴파일러가 SLES/OpenSLES.h 파일을 찾지 못해 잠시 당황 했다.

 

분명 platform 디렉토리에는 위 경로에 헤더파일이 있는데 찾지를 못해서 뭐가 문제인가 고민을 좀 했다.

 

Android.mk 파일에 -I 옵션을 추가해 줘야 하나 고민하던 차에, stlport를 사용할 때도 Application.mk 파일에 한 줄만 넣어주면 되는데, 복잡하게 되어 있을리가 없을 것 같아서, 우선 ndk-build의 -d 옵션으로 빌드 중 어떤일이 일어나는지 살펴 봤다.

 

엄청난 양의 로그가 나오고나서, 마지막 줄에 자동으로 추가되는 -I 옵션을 확인할 수 가 있었다.

 

기본으로 포함하는 include path는 platform/android-3 였다.

 

역시나 해당 platform 버전에는 SLES가 없었고 말이지...;;

 

그래서 찾아보니 target platform을 지정하는 옵션이 있더라!

 

그리고

 

TARGET_PLATFORM=android-19

 

를 추가하니 문제 해결!

 

 

참고로, 당연한 이야기 이지만 link할 library는 명시적으로 추가 해 주어야 함.

 

-lOpenSLES

 

이렇게 말이지...

 

Posted by 세월의돌
리눅스 & 안드로이드2014. 5. 12. 16:27

Open Source library를 android에서 사용하기 위해 NDK로 빌드를 해야 할 필요가 생겼다.

그 옛날(?) Gingerbread 일 때는, NDK에서 STL을 지원하지 않아서 stlport를 직접 빌드해서 넣거나, NDK에 stlport를 추가 해 놓은 NDK 버전을 사용해야 했었는데, 지금은 정말 편 해 졌더라.

MS Windows + NDK 환경에서 STL을 이용하고하 할 경우 아래와 같이 하면 간단히 해결된다. (정말 초 간단 함-0-)

 

  1. 우선 NDK를 다운로드 받아서 적당한 위치에 압축을 풀어준다.
    설치과정은 필요 없으며, 현재 최신 버전은 Android NDK, Revision 10e (May 2015) 이다.

  2. 소스 디렉토리를 구성한다.
    빌드 하고자 하는 소스는 jni 디렉토리 아래에 위치 해야 하며, 해당 디렉토리에 Android.mk / Application.mk 파일도 위치 해 있어야 한다. (ex. prj_root/jni/Android.mk, prj_root/jni/Application.mk 등)

  3. Android.mk 파일은 다른 Android.mk 파일을 참고하되, stl을 사용하기 위해서 추가해야 하는 내용은 없다.

  4. (여기가 중요!) Application.mk 파일이 중요한데, 여기에 다음과 같은 한 줄을 추가하면 C++11 STL이 shared library로 포함된다.
    APP_STL := stlport_static
    APP_STL := gnustl_shared
    APP_CPPFLAGS += -std=c++11

  5. 위 한 줄이면, include나 link path를 추가할 필요가 없다!!!
    단, 본인의 모듈에만 적용하고 싶다면, Android.mk 파일에
    LOCAL_CPPFLAGS += -std=c++11

  6. 여기에 추가로, tool chain을 선택할 수 있다. (gcc / clang)
    Application.mk 파일에 아래와 같이 추가해 주면 된다.
    NDK_TOOLCHAIN_VERSION := 4.8
    또는
    NDK_TOOLCHAIN_VERSION := clang

  7. 빌드는 (위의 예에서) prj_root 디렉토리에서, (NDK PATH)\ndk-build.cmd 를 실행하면 된다.

 

NDK_TOOLCHAIN_VERSION := clang

APP_STL := gnustl_shared

APP_CPPFLAGS += -std=c++11


이렇게 하면, 간단히 STL을 이용할 수 있다.

GB 시절(?)에 stl 사용하려고 삽질 했던걸 생각하면, 정말 껌이 되었구나!!! (__)

 

Posted by 세월의돌
리눅스 & 안드로이드2012. 3. 17. 13:24
adb shell로 target 또는 emulator의 shell을 실행 한 다음, shell에서 실행할 수 있는 바이너리를 생성할 필요가 있다.
이러한 경우 아래와 같이 Makefile을 만들어 컴파일 할 수 있다. (단, android 전체 소스가 빌드되어 있어야 함)

NDK_PATH = /home/user/android-ndk-r7b

NDK_ARCH = $(NDK_PATH)/platforms/android-14/arch-arm

SRC_ROOT = .

REF_ROOT = /home/user/source/android/out/target/product/generic/obj/

CC  = $(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc

CFLAGS  = -I$(REF_ROOT)/KERNEL_OBJ/usr/include -I$(NDK_ARCH)/usr/include/

LDFLAGS = -Wl,-rpath-link=$(REF_ROOT)/lib -L$(REF_ROOT)/lib -nostdlib $(REF_ROOT)/lib/crtbegin_dynamic.o -lc


all:

$(CC) -o abinary abinary.c $(CFLAGS) $(LDFLAGS)



Posted by 세월의돌
리눅스 & 안드로이드2011. 6. 10. 16:41
NVIDIA Debug Manager for Android NDK

NVIDIA가 Android NDK 디버깅을 위한 이클립스 플러그인을 만들었는지 모르고 있었다.
늦었지만 오늘 Google I/O를 보다 발견 한 사실! ;ㅁ;

당장 사용할 일이야 없겠지만(?) 아래 그림 하나만으로 대단한 기능이 아닐런지...
(이클립스에서 .java와 .cpp를 동시에 디버깅 할 수 있다니!)



Posted by 세월의돌