IT_Programming/Android_NDK

[NDK] Android.mk 분석

JJun ™ 2014. 3. 7. 12:01


 출처: http://millo.tistory.com/8


 

ndk를 사용하는 sample 예제들을 받으면 항상 빌드하면 에러나는 부분이 많죠.
mk파일을 잘 분석하면 왠만한 에러들은 다 잡을 수 있다는 큰 깨달음을 터득했네요 ㅎ
일단 기본적인 jni 사용할때 쓰는 Android.mk 파일 분석을 해볼게요.

 

LOCAL_PATH := $(call my-dir)

 

include $(CLEAR_VARS)

 

LOCAL_MODULE    := hellojni_lib

LOCAL_SRC_FILES := hellojni_lib.c

 

include $(BUILD_SHARED_LIBRARY)

 





LOCAL_PATH := $(call-my-dir)

이 구문은 mk파일의 처음에 기술하는 부분이며, 소스파일들의 위치를 알려주는 것인데요.
위에처럼 call-my-dir 를 하면 현재 Android.mk파일이 존재하는 디렉토리 경로를 반환 해줘요.
아래 경로에 Android.mk 파일이 있다면 /home/bec/opencv_workspace/testOpenCV/jni
이 경로를 반환. 





include $(CLEAR_VARS)

LOCAL_PATH 를 제외한 LOCAL_ 로 시작되는 변수의 값을 초기화 해주는 구문이며, 또한 전역변수 처럼 사용해요.
ex) LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES 등




LOCAL_MODULE := hellojni_lib

생성할 라이브러리 파일의 이름을 나타내요. 위에 처럼 사용하면 libhello_lib.so 라는 라이브러리가 생성.
참고로 공백문자는 포함하면 안됨.





LOCAL_SRC_FILES := hellojni_lib.c

라이브러리 생성에 필요한 소스 코드 목록을 나열 하는 부분이에요.
LOCAL_PATH 경로를 기준으로 사용하구요.
위 예처럼 되려면 Android.mk 파일과 같은 디렉토리에 hellojni_lib.c가 있어야 해요.
(맨 처음에 있는 그림처럼요.. 캡쳐하다보니 파일이름이 다른게 캡쳐 됬네요 ㅎㅎ)




include $(BUILD_SHARED_LIBRARY)

위에 내용을 바탕으로 share library 를 생성하라는 내용이에요.
BUILD_STATIC_LIBRARY, BUILD_MULTI_PREBUILT 등 여러 가지가 있어요.




번외~
LOCAL_C_INCLUDES := /home/bec/opencv_workspace/OpenCV-2.3.1/include

opencv를 보시다 보면 jni_part.cpp 파일 안에서 아래 처럼 include 해주는 부분이 있죠

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>

이렇게 참조하는 파일들의 path 위치를 지정해주는 부분이에요.
아래 같은 에러 발생시 대부분 이 부분에 문제로 발생해요.

 

 

 


 

 


 출처: http://digitanomad.blogspot.kr/2012/12/android-box2d.html


 

 

 


Android.mk 파일은 안드로이드 프로젝트를 빌드할 때 Android NDK에 코딩한 C와 C++ 소스 파일들을 설명해 주기 위해 작성하는 파일입니다.
이 파일을 이용해 작성 한 소스들을 modules로 만들 수 있습니다.

하나의 모듈은 static library나 shared library가 될 수 있습니다. shared library들은 application package에 설치되거나 복사됩니다.
또한, shared library를 생성하기 사용되어 질 수도 있습니다.


(1) LOCAL_PATH := $(call my-dir)
Android.mk 파일은 반드시 LOCAL_PATH 변수를 먼저 선언해야 합니다. 개발 소스 트리에서 소스 파일들의 위치를 나타내기 위해 사용됩니다.
빌드 시스템에서 제공하는 'my-dir' 매크로 함수는 현재 디렉토리의 경로를 리턴합니다.


(2) include $(CLEAR_VARS)
빌드 시스템에서 제공하는 CLEAR_VARS 변수는 LOCAL_PATH를 제외한 LOCAL_XXX 형식의 많은 변수들을 초기화 시켜줍니다.
모든 빌드 제어 파일들의 변수들은 전역변수이기 때문에 초기화가 필요합니다.


(3) LOCAL_MODULE := game_shared
LOCAL_MOULDE 변수는 Android.mk 파일에 있는 각 모듈을 구분하기 위해 지정해줘야 합니다. 변수명은 반드시 유일(unique)해야 하고 공백이 있어서는 안됩니다.
빌드 시스템은 생성되는 파일에 따라 접두사(prefix)나 접미사(suffix)가 붙습니다. 예를 들면, foo라는 shared library module은 libfoo.so가 됩니다.
그림에서는 변수에 game_shared를 넣었으니 libgame_shared.so라는 이름의 파일이 생성될 것입니다.


(4) LOCAL_MODULE_FILENAME := libgame
이 변수는 LOCAL_MODULE에서 생성되는 파일들의 이름을 재정의 해주는 역할을 하며, 써도 되고 안써도 되는 옵션 변수입니다.
기본 설정으로는 module <foo>는 항상 static library 인 lib<foo>.a나 shared library인 lib<foo>.so를 생성합니다.
LOCAL_MODULE_FILENAME을 정의하면 이름을 바꿀 수 있습니다. 그림에서는 변수에 libgame이라고 넣었으니, libgame.so라는 파일이 생성됩니다.


(5) LOCAL_SRC_FILES
모듈을 빌드할 때 사용하는 소스 파일들의 리스트입니다. 컴파일 할 파일들(.cpp)만 리스트에 게재해두면, 빌드 시스템에서 자동으로 의존성(dependencies)을
처리해줄 것입니다. 
그리고 파일 리스트를 작성할 때 경로명에 유닉스 스타일의 앞 슬래쉬(/)를 사용해야 합니다. 윈도우 스타일의 백 슬래쉬(\)을 사용하면
올바르게 처리되지 않습니다.
 LOCAL_SRC_FILE에는 개발하면서 생성한 cpp 파일을 추가합니다.

(6) LOCAL_C_INCLUDES
모든 소스들(C,C++와 Assembly)을 컴파일 할 때, 추가적으로 덧붙여서 포함(include)하는 경로 리스트라고 할 수 있습니다. 예를 들면,
LOCAL_C_INCLUDES := sources/foo
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo는 같습니다.

(7) LOCAL_WHOLE_STATIC_LIBRARIES
이 변수는 "whole archives"로서 사용되는 라이브러리 모듈을 Linker에 표현하기 위해 사용합니다.
--whole-archive flag에 대해서는 GNU linker's documentation을 찾아보시기 바랍니다.

그리고 이 변수는 여러 static library간에 서로 물고 물리는 의존성(circular dependencies)를 가질 때 유용합니다.
shared library를 빌드할 때, whole static library들로부터 만들어진 모든 object 파일들은 최종 바이너리 파일에 강제적으로 추가됩니다.

위 그림에서는 box2d_static을 추가하여 libgame.so파일에 강제적으로 box2d 관련 object 파일들이 추가되도록 하였습니다.

(8) include $(BUILD_SHARED_LIBRARY)
빌드 시스템에서 제공하는 BUILD_SHARED_LIBRARY는 가장 최근에 작성된 'include $(CLEAR_VARS)' 이후에 정의된 LOCAL_XXX 변수들의 모든 정보를 모으고,
무엇을 빌드할지 정하고, 그것을 어떻게 수행할지를 담당하는 GNU Makefile script 파일을 가리키는 변수입니다.


(9) import-module
$(call import-module,<name>)
NDK_MODULE_PATH 환경 변수로 설정한 디렉토리에서 <name>으로 이름 붙여진 모듈을 찾아서 그 모듈의 Android.mk 파일을 자동으로 포함시킵니다.
그림에서는 Box2D 디렉토리를 추가해서 Box2D 디렉토리에 있는 Android.mk 파일을 추가하였습니다.