본문 바로가기

Programming/Android

Android.mk란?

Android.mk란? (https://developer.android.com/ndk/guides/android_mk.html?hl=ko)

  • 이 페이지는 ndk-build가 사용하는 Android.mk 빌드 파일의 구문에 대해 설명한다.

  • 개요

    • Android.mk 파일은 프로젝트의 jni/ 디렉토리에 속한 하위 디렉토리에 있으며, 빌드 시스템에 대한 소스 및 공유 라이브러리를 설명한다. 이 파일은 실제로는 빌드 시스템이 한 번 또는 그 이상 파싱하는 작은 GNU 메이크파일 프래그먼트이다. Android.mk 파일은 Application.mk, 빌드 시스템, 환경 변수가 정의되지 않은 상태로 남겨두는 프로젝트 전반의 설정을 정의하는 데 유용하다. 이 파일은 특정 모듈에 대한 프로젝트 전체 설정을 재정의할 수도 있다.

    • Android.mk의 구문을 사용해 소스를 모듈로 그룹화할 수 있다. 모듈은 정적 라이브러리, 공유 라이브러리, 독립형 실행 파일이다. 각각의 Android.mk 파일에서 하나 이상의 모듈을 정의할 수 있고 여러 모듈에서 같은 소스 파일을 사용할 수 있다. 빌드 시스템은 공유 라이브러리를 애플리케이션 패키지에 넣을 뿐이다. 또한 정적 라이브러리는 공유 라이브러리를 생성할 수 있다.

    • 라이브러리 패키징과 더불어, 빌드 시스템은 개발자를 위해 다양한 기타 세부 사항을 처리해 준다. 예를 들어, 헤더 파일을 나열하거나 Android.mk 파일에 생성된 파일 간의 종속성을 명시할 필요가 없다. NDK 빌드 시스템이 이러한 관계들을 자동으로 계산해주기 때문이다. 따라서 Android.mk 파일을 손댈 필요 없이 향후 NDK 릴리스의 새로운 툴체인/플랫폼 지원을 이용할 수 있을 것이다.

    • 이 파일의 구문은 전체 Android 오픈소스 프로젝트와 함께 배포되는 Android.mk 파일에 사용되는 구문과 매우 흡사하다. 이들을 사용하는 빌드 시스템 구현은 서로 다르지만, 의도적으로 디자인 단계에서 이처럼 유사하게 만든 이유는 애플리케이션 개발자들이 외부 라이브러리용 소스 코드를 더 쉽게 재사용할 수 있도록 하기 위함이다.

  • 기본 사항

    • 구문을 자세히 살펴보기 전에, 먼저 Android.mk 파일에 들어 있는 내용에 대한 기초 사항부터 이해하는 것이 도움이 된다. 이 섹션에서는 그런 목적에 맞춰 Hello-JNI 샘플에 있는 Android.mk 파일을 사용해 파일에 있는 각 줄의 역할을 설명한다.

    • Android.mk 파일은 다음과 같이 LOCAL_PATH 변수에 대한 정의로 시작해야 한다.

      LOCAL_PATH := $(call my-dir)
    • 이 변수는 개발 트리에 있는 소스 파일의 위치를 나타낸다. 여기서 빌드 시스템이 제공하는 매크로 함수 my-dir 는 현재 디렉토리(Android.mk 파일 자체를 포함한 디렉토리)의 경로를 반환한다.

    • 그 다음 줄에서는 빌드 시스템이 제공하는 값을 가진 CLEAR_VARS 변수를 선언한다.

      include $(CLEAR_VARS)
    • CLEAR_VARS 변수는 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES와 같은 수많은 LOCAL_XXX 변수를 자동으로 지우는 GNU Makefile을 가리킨다. 참고로, 이 변수가 LOCAL_PATH를 지우지는 않는다. 시스템에서는 모든 변수가 전역 변수인 단일 GNU Make 실행 컨텍스트의 모든 빌드 컨트롤 파일을 파싱하기 때문에 이 변수는 자신의 값을 유지해야 한다. 각각의 모듈을 설명하기 전에 이 변수를 (재)선언해야 한다.

    • 다음으로, LOCAL_MODULE 변수가 빌드하려는 모듈의 이름을 저장한다. 이 변수는 애플리케이션 내 모듈당 한 번씩 사용한다.

      LOCAL_MODULE := hello-jni
    • 각 모듈 이름은 고유해야 하고, 공백을 하나라도 포함하면 안 된다. 빌드 시스템은 최종 공유 라이브러리 파일을 생성할 때 LOCAL_MODULE에 할당하는 이름에 알맞은 접두사와 접미사를 자동으로 추가한다. 예를 들어, 위에 나와 있는 예시대로 실행하면 libhello-jni.so 라는 라이브러리가 생성된다. **참고: 모듈 이름이 이미 'lib'로 시작하는 경우 빌드 시스템은 추가적인 'lib' 접두사를 앞에 추가하지 않고, 모듈 이름을 그대로 받아들인 후 '.so' 확장자를 추가한다. 예를 들어, 원래 이름이 'libfoo.c'인 소스 파일은 계속 'libfoo.so'라는 공유 객체 파일을 생성한다. 이 동작은 Android 플랫폼 소스가 'Android.mk' 파일에서 생성하는 라이브러리를 지원하기 위한 것으로, 이러한 모든 라이브러리의 이름은 'lib'으로 시작한다.

    • 다음 줄에는 소스 파일이 열거되며, 공백으로 여러 파일을 구분한다.

      LOCAL_SRC_FILES := hello-jni.c
    • LOCAL_SRC_FILES 변수는 모듈에 빌드할 C 및 C++ 소스 파일의 목록을 포함해야 한다.

    • 마지막 명령줄은 시스템이 모든 것을 하나로 연결하는 데 도움이 된다.

      include $(BUILD_SHARED_LIBRARY)
    • BUILD_SHARED_LIBRARY 변수는 가장 최근의 include 이후로 LOCAL_XXX 변수에 정의한 모든 정보를 수집하는 GNU Makefile 스크립트를 가리킨다. 이 스크립트에 따라 빌드할 대상과 그 방법이 결정된다.

    • 샘플 디렉토리에는 더 복잡한 예시가 있으며, 주석 처리된 Android.mk 파일을 살펴볼 수 있었다. 그 밖에도, 샘플: native-activity에 샘플의 Android.mk 파일에 대한 자세한 설명이 나와있다. 마지막으로, 변수와 매크로에는 이 섹션에서 소개한 변수들에 대한 추가 정보가 설명되어 있다.

  • 변수와 매크로

    • 이 빌드 시스템은 Android.mk 파일에서 사용할 수 있는 변수를 최대한 많이 제공한다. 이들 변수에는 대부분 미리 할당된 값이 포함되어 있다. 다른 변수들은 개발자가 직접 값을 할당한다.

    • 이러한 변수 외에, 자체적으로 임의의 변수를 정의할 수도 있다. 그럴 경우, NDK 빌드 시스템에 다음 변수 이름이 예약되어 있다는 점에 유의해라.

      1. LOCAL_로 시작되는 이름(예: LOCAL_MODULE)

      2. PRIVATE_, NDK__, APP으로 시작되는 이름. 빌드 시스템은 이러한 이름을 내부적으로 사용한다.

      3. 소문자로 된 이름(예: my-dir). 이 빌드 시스템은 이러한 이름 역시 내부적으로 사용한다.

    • Android.mk 파일에 편의상 자체 변수를 정의할 필요가 있을 경우에는 이름 앞에 MY_를 추가하는 것이 좋다.

  • NDK에서 정의된 include 변수

    • 이 섹션에서는 빌드 시스템이 Android.mk 파일을 파싱하기 전에 정의하는 GNU Make 변수에 대해 설명한다. 특정 상황에서는 NDK가 매번 이들 변수 중 일부에 대해 다른 정의를 사용해 Android.mk 파일을 여러 차례 파싱할 수도 있다.

      1) CLEAR_VARS

      • 이 변수는 아래의 "개발자 정의 변수" 섹션에 나열되어 있는 거의 모든 LOCAL_XXX 변수의 정의를 해제하는 빌드 스크립트를 포인팅한다. 새 모듈을 설명하기 전에 이 변수를 사용해 스크립트를 포함해라. 이 변수를 사용하기 위한 구문은 다음과 같다.

        include $(CLEAR_VARS)

      2) BUILD_SHARED_LIBRARY

      • 이 변수는 LOCAL_XXX 변수에서 제공한 모듈에 대한 모든 정보를 수집하는 빌드 스크립트를 가리키고, 나열한 소스에서 대상 공유 라이브러리의 빌드 방법을 결정한다. 이 스크립트를 사용하려면 최소한 LOCAL_MODULE과 LOCAL_SRC_FILES에는 이미 값을 할당한 상태여야 한다.

      • 이 변수를 사용하기 위한 구문은 다음과 같다.

        include $(BUILD_SHARED_LIBRARY)
      • 공유 라이브러리 변수를 사용하려면 빌드 시스템이 .so 확장자를 가진 라이브러리 파일을 생성한다.

      3) BUILD_STATIC_LIBRARY

      • 정적 라이브러리를 빌드하는 데 사용되는 BUILD_SHARED_LIBRARY의 변형. 이 빌드 시스템은 정적 라이브러리를 프로젝트/패키지로 복사하지는 않지만, 정적 라이브러리를 사용해 공유 라이브러리를 빌드할 수 있다. 이 변수를 사용하기 위한 구문은 다음과 같다.

        include $(BUILD_STATIC_LIBRARY)
      • 정적 라이브러리 변수를 사용하면 빌드 시스템이 .a 확장자를 가진 라이브러리를 생성한다.

      4) PREBUILT_SHARED_LIBRARY

이 밑으로는 문서를 참조하자

'Programming > Android' 카테고리의 다른 글

AndroidManifest란?  (0) 2019.05.19
Application.mk란?  (0) 2019.05.19
ABI란?  (0) 2019.04.22
NDK란?  (0) 2019.04.17
Gradle이란?  (0) 2019.04.16