Android.mk

このページでは、Android NDK と C ソースファイルや C++ ソースファイルを結びつける Android.mk ビルドファイルの構文について説明します。

概要

Android.mk ファイルはプロジェクトの jni/ ディレクトリのサブディレクトリにあり、ビルドシステムに対してソースと共有ライブラリを伝える役割を果たします。 このファイルは GNU Makefile のごく一部であり、ビルドシステムによって一度以上解析されます。 Android.mk ファイルは、Application.mk、ビルドシステム、環境変数では定義されていない、プロジェクト全体にわたる設定を定義するために使われます。 特定のモジュールのために、プロジェクト全体にわたる設定をオーバーライドすることもできます。

Android.mk の構文では、ソースを「モジュール」にグループ分けすることができます。 モジュールは静的ライブラリ、共有ライブラリ、スタンドアロン実行可能ファイルのいずれかです。 Android.mk ごとに 1 つ以上のモジュールを定義することができます。また、同じソースファイルを複数のモジュールで使用できます。 ビルドシステムは共有ライブラリをアプリ パッケージに配置するだけです。 また、静的ライブラリから共有ライブラリを生成することができます。

ビルドシステムはライブラリをパッケージ化するだけでなく、デベロッパーの代わりにさまざまな詳細な処理を行います。これにより、たとえばヘッダー ファイルや生成されたファイル間の明示的な依存関係を、自身で Android.mk ファイルに記載する必要がなくなります。 代わりに NDK ビルドシステムが、自動でこれらの関係を計算します。 その結果、Android.mk ファイルを編集しなくても、今後の NDK リリースで、新しいツールチェーンまたはプラットフォームのサポートを受けることができます。

このファイルの構文は、Android Open Source Project 全体で公開されている 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_MODULELOCAL_SRC_FILESLOCAL_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 ビルドシステムが次の変数名を予約していることに注意してください。

  • LOCAL_MODULE など、LOCAL_ で始まる名前。
  • PRIVATE_NDK_APP で始まる名前。ビルドシステムはこれらを内部で使用します。
  • my-dir などの小文字名。これらも、ビルドシステムが内部で使用します。

Android.mk ファイルで独自の変数を定義する必要がある場合は、名前の前に MY_ を付けることをお勧めします。

NDK 定義の変数

このセクションでは Android.mk ファイルを解析する前にビルドシステムが定義する GNU Make 変数について説明します。 場合によっては、これらの変数の一部の定義を変えて、NDK が Android.mk ファイルを複数回解析することがあります。

CLEAR_VARS

この変数は、後述の「デベロッパー定義の変数」のセクションにあるほぼすべての LOCAL_XXX 変数の定義をクリアするビルド スクリプトを指します。 この変数を使用してこのスクリプトをインクルードしてから新しいモジュールを指定します。 この変数に使用する構文は次のとおりです。

include $(CLEAR_VARS)

BUILD_SHARED_LIBRARY

この変数は、LOCAL_XXX 変数で指定したモジュールに関するすべての情報を収集し、リストしたソースからターゲットの共有ライブラリをビルドする方法を指定するビルド スクリプトを指します。 モジュール このスクリプトを使用する場合、少なくとも LOCAL_MODULELOCAL_SRC_FILES に値を指定しておく必要があることに注意してください(これらの変数の詳細については、モジュール記述変数をご覧ください)。

この変数に使用する構文は次のとおりです。

include $(BUILD_SHARED_LIBRARY)

共有ライブラリ変数によって、ビルドシステムが .so 拡張子のライブラリ ファイルを生成します。

BUILD_STATIC_LIBRARY

静的ライブラリのビルドに使用する BUILD_SHARED_LIBRARY のバリアント。ビルドシステムは静的ライブラリをプロジェクトまたはパッケージにコピーしませんが、それらを共有ライブラリのビルドに使用することができます(後述の LOCAL_STATIC_LIBRARIESLOCAL_WHOLE_STATIC_LIBRARIES をご覧ください)。 この変数に使用する構文は次のとおりです。

include $(BUILD_STATIC_LIBRARY)

静的ライブラリ変数によって、ビルドシステムが .a 拡張子のライブラリを生成します。

PREBUILT_SHARED_LIBRARY

事前にビルドされた共有ライブラリの指定に使用するビルド スクリプトを指します。BUILD_SHARED_LIBRARYBUILD_STATIC_LIBRARY の場合と異なり、ここでは LOCAL_SRC_FILES の値をソース ファイルにはできません。 foo/libfoo.so のように、事前にビルドされた共有ライブラリへのシングルパスである必要があります。 この変数に使用する構文は次のとおりです。

include $(PREBUILT_SHARED_LIBRARY)

LOCAL_PREBUILTS 変数を使用して、別のモジュールの事前にビルドされたライブラリを参照することもできます。 事前ビルドの詳細については、事前ビルド ライブラリの使用をご覧ください。

PREBUILT_STATIC_LIBRARY

事前にビルドされた静的ライブラリが対象であることを除き、PREBUILT_SHARED_LIBRARY と同じです。事前ビルドの詳細については、事前ビルド ライブラリの使用をご覧ください。

TARGET_ARCH

Android Open Source Project が指定したターゲット CPU アーキテクチャの名前。どの ARM 対応ビルドにも、CPU アーキテクチャ リビジョンまたは ABI(後述の TARGET_ARCH_ABI を参照)から独立している arm を使用してください。

この変数の値は Android.mk ファイルで定義した APP_ABI 変数の値になります。APP_ABI 変数は、システムが Android.mk ファイルを解析する前に読み込まれます。

TARGET_PLATFORM

ビルドシステムのターゲットの Android API レベル番号。たとえば、Android 5.1 のシステム イメージには Android API レベル 22: android-22 が対応しています。プラットフォーム名と Android システム イメージの対応については、Android NDK ネイティブ API の一覧をご覧ください。以下はこの変数に使用する構文の例です。

TARGET_PLATFORM := android-22

TARGET_ARCH_ABI

この変数には、ビルドシステムが Android.mk ファイルを解析するときにターゲットとする CPU とアーキテクチャの名前を指定します。 以下の値の中から複数個指定することも可能です。その場合は各ターゲットを空白で区切ります。 表 1 にサポート対象の各 CPU とアーキテクチャに使用できる ABI 設定を示します。

表 1 各 CPU とアーキテクチャの ABI 設定

CPU とアーキテクチャ 設定
ARMv5TEarmeabi
ARMv7armeabi-v7a
ARMv8 AArch64arm64-v8a
i686x86
x86-64x86_64
mips32(r1)mips
mips64(r6)mips64
すべてall

次の例は、ARMv8 AArch64 をターゲットの CPU と ABI の組み合わせとして設定する方法を示します。

TARGET_ARCH_ABI := arm64-v8a

注: Android NDK 1.6_r1 までは、この変数は arm として定義されています。

アーキテクチャ ABI と関連する互換性の問題については、ABI 管理をご覧ください。

今後、新しいターゲット ABI には別の値が用意される予定です。

TARGET_ABI

ターゲットの Android API レベルと ABI を連結すると、実機向けの特定のターゲット システム イメージに対してテストを実施する際に非常に便利です。 たとえば、Android API レベル 22 で実行される 64 ビットの ARM 端末は、次のように指定します。

TARGET_ABI := android-22-arm64-v8a

: Android NDK 1.6_r1 までは、既定値は android-3-arm でした。

モジュール記述変数

このセクションの変数で、ビルドシステムに対するモジュールの説明を記述します。モジュールの記述は次の基本的なフローに従う必要があります。

    1. CLEAR_VARS 変数を使用して、モジュールに紐づいている変数の初期化、または定義のクリアを行います。
    2. モジュールの記述に使用する変数に値を指定します。
    3. BUILD_XXX 変数を使用して、モジュールに対して適切なビルド スクリプトを使用するように NDK ビルドシステムを設定します。

LOCAL_PATH

この変数は現在のファイルのパスを返すために使用されます。Android.mk ファイルの最初にこれを定義する必要があります。 指定方法については次の例を参考にしてください。

LOCAL_PATH := $(call my-dir)

CLEAR_VARS が指すスクリプトは、この変数をクリアしません。したがって、Android.mk ファイルに複数のモジュールが記述されていても、一度定義するだけで済みます。

LOCAL_MODULE

この変数にモジュールの名前を指定します。すべてのモジュール名の中で一意でなければならず、空白は使用できません。 この変数を定義してからスクリプト(CLEAR_VARS に対するスクリプト以外)をインクルードする必要があります。 lib 接頭辞または .so.a ファイル拡張子はビルドシステムが自動で付与するので、自分で追加する必要はありません。 Android.mk ファイルと Application.mk ファイル内では、変更していない名前でモジュールを参照します。 たとえば、次の行では libfoo.so という共有ライブラリ モジュールが生成されます。

LOCAL_MODULE := "foo"

生成されたモジュールに libLOCAL_MODULE の値を付与したもの以外の名前を付けたい場合、LOCAL_MODULE_FILENAME 変数を使用して、生成されたモジュールに自分で選択した名前を付けることができます。

LOCAL_MODULE_FILENAME

この任意の変数で、デフォルトでビルドシステムが生成したファイルに付ける名前をオーバーライドすることができます。 たとえば、LOCAL_MODULE の名前が foo の場合、生成されたファイルをシステム側で libnewfoo として参照するように強制することができます。 指定方法については次の例を参考にしてください。

LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo

共有ライブラリ モジュールの場合、この例では libnewfoo.so というファイルが生成されます。

: ファイルパスまたはファイル拡張子はオーバーライドできません。

LOCAL_SRC_FILES

この変数には、モジュールを生成するためにビルドシステムが使用するソースファイルのリストが含まれています。 ビルドシステムは関連する依存関係を自動的に計算するため、ビルドシステムがコンパイラーに実際に渡すファイルのみを記載します。

ここでは、相対(LOCAL_PATH に対する)ファイルパスと絶対ファイルパスの両方を使用できます。

絶対ファイルパスの使用はお勧めしません。相対パスを使用すると、Android.mk ファイルの移植性が高くなります。

注: ビルドシステムは Windows スタイルのバックスラッシュ(\)を正しく処理できないため、ビルドファイルでは必ず Unix スタイルのフォワード スラッシュ(/)を使用してください。

LOCAL_CPP_EXTENSION

この任意の変数を使用して、C++ ソースファイルに .cpp 以外のファイル拡張子を指定することができます。 たとえば、次の行では拡張子を .cxx に変更します(ドットを含めて指定する必要があります)。

LOCAL_CPP_EXTENSION := .cxx

NDK r7 以降は、この変数で複数の拡張子を指定できます。次に例を示します。

LOCAL_CPP_EXTENSION := .cxx .cpp .cc

LOCAL_CPP_FEATURES

この任意の変数で、コードが特定の C++ 機能に依存していることを示します。これにより、ビルドプロセス中に適切なコンパイラー フラグとリンカーフラグが有効になります。 事前にビルドされたバイナリの場合、この変数でバイナリが依存する機能も宣言することで、最終リンクが正常に行われるようになります。 LOCAL_CPPFLAGS 定義で直接 -frtti-fexceptions を有効にする代わりに、この変数を使用することをお勧めします。

この変数を使用すると、ビルドシステムがモジュールごとに適切なフラグを使用できるようになります。一方 LOCAL_CPPFLAGS を使用すると、実際に必要かどうかにかかわらず、コンパイラーはすべてのモジュールに対して指定のフラグをすべて使用します。

たとえば、コードで RTTI(ランタイム タイプ情報)を使用することを示すには、次のように記述します。

LOCAL_CPP_FEATURES := rtti

コードが C++ の例外を使用することを示すには、次のように記述します。

LOCAL_CPP_FEATURES := exceptions

この変数に複数の値を指定することもできます。次に例を示します。

LOCAL_CPP_FEATURES := rtti features
値はどの順番で記述してもかまいせん。

LOCAL_C_INCLUDES

この任意の変数で、NDK root ディレクトリからの相対パスのリストを指定すると、すべてのソース(C、C++、アセンブリ)をコンパイルするときにインクルード検索パスに追加されます。 次に例を示します。

LOCAL_C_INCLUDES := sources/foo

次の方法もあります。

LOCAL_C_INCLUDES := $(LOCAL_PATH)//foo

この変数を定義してから、LOCAL_CFLAGS または LOCAL_CPPFLAGS によって対応するインクルード フラグを設定します。

ビルドシステムは、ndk-gdb を使用してネイティブ デバッグを起動するときに自動的に LOCAL_C_INCLUDES パスも使用します。

LOCAL_CFLAGS

この任意の変数で、C ソースファイルと C++ ソースファイルのビルド時にビルドシステムに渡すコンパイラー フラグを設定します。 この機能は追加のマクロ定義やコンパイラー オプションの指定に有用です。

Android.mk ファイルで、最適化レベルまたはデバッグレベルを変更しないでください。これらの設定は、ビルドシステム側で Application.mk ファイル内の関連情報を使用して自動的に処理します。 この処理により、デバッグ時に役立つデータファイルがビルドシステムによって生成されます。

注: android-ndk-1.5_r1 では、対応するフラグは C++ ソースファイルには適用されず、C ソースファイルにのみ適用されます。 現在は、Android ビルドシステムの動作全体にフラグを適用できるようになっています(LOCAL_CPPFLAGS を使用すると、C++ ソース専用のフラグを指定可能)。

次のように記述して、追加のインクルード パスを指定できます。

LOCAL_CFLAGS += -I<path>,
ただし、この目的のためには LOCAL_C_INCLUDES を使用することをお勧めします。こちらの方法では、ndk-gdb によるネイティブ デバッグに利用できるパスも使用可能になります。

LOCAL_CPPFLAGS

C++ ソースファイルのみをビルドするときに渡される任意のコンパイラー フラグです。 コンパイラーのコマンドラインで LOCAL_CFLAGS のあとに表示されます。

注: android-ndk-1.5_r1 では、対応するフラグは C ソースと C++ ソースの両方に適用されます。 これは Android ビルドシステム全体に適合するように修正されています。C ソースと C++ ソースの両方にフラグを指定するには、LOCAL_CFLAGS を使用します。

LOCAL_STATIC_LIBRARIES

この変数には、現在のモジュールが依存している静的ライブラリ モジュールのリストを指定します。

現在のモジュールが共有ライブラリまたは実行可能ファイルの場合、この変数によって、生成されたバイナリにこれらのライブラリが強制的にリンクされます。

現在のモジュールが静的ライブラリの場合は、この変数によって、現在のモジュールに依存している他のモジュールも、リストにあるライブラリに依存することが示されるだけです。

LOCAL_SHARED_LIBRARIES

この変数は、このモジュールが実行時に依存する共有ライブラリ モジュールのリストです。 この情報は、リンク時に対応する情報を生成ファイルに組み込むために必要です。

LOCAL_WHOLE_STATIC_LIBRARIES

この変数は LOCAL_STATIC_LIBRARIES のバリアントで、関連付けられているライブラリ モジュールを完全アーカイブとしてリンカーで処理する必要があることを示します。 完全アーカイブの詳細については、GNU リンカーのドキュメント--whole-archive フラグをご覧ください。

複数の静的ライブラリ間で依存関係が循環している場合に、この変数が役に立ちます。 この変数を使用して共有ライブラリをビルドすると、ビルドシステムは、静的ライブラリのすべてのオブジェクトを最終バイナリに強制的に追加します。 ただし、これは実行可能ファイルの生成には当てはまりません。

LOCAL_LDLIBS

この変数には、共有ライブラリまたは実行可能ファイルのビルドに使用する追加のリンカーフラグのリストが含まれます。 特定のシステム ライブラリ名を渡すには、-l 接頭辞を使用します。 たとえば、次の例では、読み込み時に /system/lib/libz.so にリンクするモジュールを生成するようにリンカーに指示しています。

LOCAL_LDLIBS := -lz

この NDK リリースでリンク可能な公開システム ライブラリの一覧については、Android NDK ネイティブ API をご覧ください。

注: 静的ライブラリ用にこの変数を定義すると、ビルドシステムはこの変数を無視し、ndk-build によって警告が表示されます。

LOCAL_LDFLAGS

共有ライブラリまたは実行可能ファイルのビルドに使用する、ビルドシステム用のその他のリンカーフラグのリストです。 たとえば、次の例では、ld.gold がデフォルトの ARM/X86 GCC 4.6+ で、ld.bfd リンカーを使用します。

LOCAL_LDFLAGS += -fuse-ld=bfd

注: 静的ライブラリ用にこの変数を定義すると、ビルドシステムはこの変数を無視し、ndk-build によって警告が表示されます。

LOCAL_ALLOW_UNDEFINED_SYMBOLS

既定では、共有ライブラリをビルドしようとしてビルドシステムで未定義の参照が発生した場合は、Undefined symbol エラーがスローされます。 このエラーは、ソースコードのバグの検出に役立ちます。

このチェックを無効にするには、この変数を true に設定します。この設定により、共有ライブラリが実行時に読み込まれる可能性があります。

注: 静的ライブラリ用にこの変数を定義すると、ビルドシステムはこの変数を無視し、ndk-build によって警告が表示されます。

LOCAL_ARM_MODE

デフォルトでは、ビルドシステムは ARM ターゲット バイナリを thumb モードで生成します。このモードでは、命令は 16 ビット長で、thumb/ ディレクトリの STL ライブラリにリンクされます。この変数を arm と定義すると、ビルドシステムは、強制的にモジュールのオブジェクト ファイルを 32 ビット arm モードで生成します。 指定方法については次の例を参考にしてください。

LOCAL_ARM_MODE := arm

ソースファイル名に .arm 拡張子を追加して、特定のソースだけを arm モードでビルドするように、ビルドシステムに指示することもできます。 たとえば、次の例では、bar.c のコンパイルは常に ARM モードで行い、foo.c のビルドは LOCAL_ARM_MODE の値に従って行うように、ビルドシステムに指示しています。

LOCAL_SRC_FILES := foo.c bar.c.arm

注: Application.mk ファイルで APP_OPTIMdebug に設定して、ARM バイナリを生成するようにビルドシステムに強制することもできます。debug を指定すると、ツールチェーン デバッガは Thumb コードを正しく処理できないため、強制的に ARM ビルドが実行されます。

LOCAL_ARM_NEON

この変数は armeabi-v7a ABI をターゲットとしている場合のみ重要になります。アセンブリ ファイルでの ARM 拡張 SIMD(NEON)命令に加えて、C ソースファイルと C++ ソースファイルで NEON GCC intrinsic を使用できます。

ARMv7 ベースのすべての CPU が NEON 命令セットの拡張機能をサポートするわけではないことに注意してください。このため、ランタイム検出を実行して、このコードを実行時に安全に使用できるようにします。 詳細については、NEON サポートおよび cpufeatures ライブラリをご覧ください。

または .neon 拡張子を使用して、ビルドシステムで特定のファイルだけ NEON を有効にしてビルドするように指定することも可能です。 次の例では、ビルドシステムが、foo.c を Thumb および NEON 対応で、bar.c を Thumb 対応で、 zoo.c を ARM と NEON 対応でコンパイルします。

LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon

両方の拡張子を使用する場合、.arm.neon よりも先にする必要があります。

LOCAL_DISABLE_NO_EXECUTE

Android NDK r4 で「NX ビット」セキュリティ機能のサポートが追加されました。これは既定で有効になっていますが、この変数を true に設定して無効にすることができます。 設定を無効にする理由が明白でない限り、この操作はお勧めしません。

この機能は ABI を変更するものではありません。ARMv6+ CPU 端末をターゲットとするカーネル上で有効になるだけです。 この機能が有効になっているマシンコードは、以前の CPU アーキテクチャを実行している端末で変更なしで実行されます。

詳細については、Wikipedia:NX ビットおよび GNU stack quickstart をご覧ください。

LOCAL_DISABLE_RELRO

既定では、NDK は読み取り専用再配置および GOT 保護でコードをコンパイルします。 この変数は、ランタイム リンカーに対して特定のメモリ領域を再配置後に読み取り専用とマークするように指示することで、特定のセキュリティ攻撃(GOT 上書きなど)による被害を防ぎます。 これらの保護が有効なのは Android API レベル 16 以上であることに注意してください。このレベル未満の API でもコードは実行できますが、メモリは保護されません。

この変数は既定で有効になっていますが、値を true に設定して無効にすることができます。 設定を無効にする理由が明白でない限り、この操作はお勧めしません。

詳細については、RELRO: 読み取り専用再配置RedHat Enterprise Linux でのセキュリティの機能強化(セクション 6)をご覧ください。

LOCAL_DISABLE_FORMAT_STRING_CHECKS

既定では、ビルドシステムはフォーマット文字列を保護してコードをコンパイルします。この方式のコンパイルでは、printf スタイルの関数で非定数フォーマット文字列が使用されている場合、コンパイル エラーが発生します。

この保護は既定で有効になっていますが、この変数の値を true に設定すると無効にすることができます。 設定を無効にする理由が明白でない限り、この操作はお勧めしません。

LOCAL_EXPORT_CFLAGS

この変数には一連の C/C++ コンパイラー フラグを指定します。これは、LOCAL_STATIC_LIBRARIES 変数や LOCAL_SHARED_LIBRARIES 変数によってこのフラグを利用する他のモジュールの LOCAL_CFLAGS 定義に追加します。

たとえば、foo と、foo に依存する bar のモジュールのペアについて考えてみましょう。

include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_CFLAGS := -DFOO=1
include $(BUILD_STATIC_LIBRARY)


include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_CFLAGS := -DBAR=2
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)

ここでは、ビルドシステムが、bar.c のビルド時にフラグ -DFOO=1-DBAR=2 をコンパイラーに渡しています。 また、エクスポートされたフラグがモジュールの LOCAL_CFLAGS の先頭に付加されるため、簡単にオーバーライドできるようになります。

さらに、モジュール間の関係が推移的です。つまり、zoobar に依存していると、foo にも依存していることになり、zoofoo からエクスポートされるすべてのフラグも継承します。

ビルドシステムは、ローカルビルド(フラグをエクスポートしているモジュールのビルドなど)ではエクスポートされるフラグを使用しません。 したがって、上記の例では、ビルドシステムは、foo/foo.c のビルドで -DFOO=1 をコンパイラーに渡しません。 ローカルビルドでは、LOCAL_CFLAGS を使用します。

LOCAL_EXPORT_CPPFLAGS

この変数は LOCAL_EXPORT_CFLAGS と同じですが、C++ フラグ専用です。

LOCAL_EXPORT_C_INCLUDES

この変数は LOCAL_EXPORT_CFLAGS と同じですが、C インクルード パス用です。たとえば、bar.c がモジュール foo からヘッダーを組み込む必要がある場合に有用です。

LOCAL_EXPORT_LDFLAGS

この変数は LOCAL_EXPORT_CFLAGS と同じですが、リンカー フラグ用です。

LOCAL_EXPORT_LDLIBS

この変数は LOCAL_EXPORT_CFLAGS と同様に、ビルドシステムに、特定のシステム ライブラリの名前をコンパイラーに渡すように指示します。 指定した各ライブラリの名前の前に -l を付けます。

ビルドシステムは、モジュールの LOCAL_LDLIBS 変数の値にインポートされたリンカーフラグを付与することに注意してください。 Unix リンカーの仕組みにより、このような動作になります。

この変数は、通常、モジュール foo が静的ライブラリで、システム ライブラリに依存するコードを含む場合に有用です。 LOCAL_EXPORT_LDLIBS を使用すると、依存関係をエクスポートできます。 次に例を示します。

include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)

この例では、ビルドシステムが libbar.so をビルドするときに、リンカー コマンドの終わりに -llog を付けます。 これを行うことで、libbar.sofoo に依存するため、システムのロギング ライブラリにも依存することをリンカーに通知します。

LOCAL_SHORT_COMMANDS

モジュールにソースや静的ライブラリまたは共有ライブラリが非常に多く含まれている場合、この変数を true に設定します。 これを行うことで、ビルドシステムは、中間オブジェクト ファイルやリンク ライブラリを含むアーカイブに @ 構文を強制的に使用します。

Windows ではコマンドラインの許容文字数が最大 8191 文字であり、複雑なオブジェクトには足りない可能性があるため、この機能が特に役に立ちます。 また、リストファイル内にほぼすべてのコンパイラー フラグを持つ、個々のソースファイルのコンパイルにも効果があります。

true 以外のすべての値は既定の動作に帰属することに注意してください。 APP_SHORT_COMMANDSApplication.mk ファイルに定義して、プロジェクト内のすべてのモジュールにこの動作を強制することもできます。

この機能を有効にするとビルドの速度が下がるため、デフォルトでこの機能を有効にしないことをお勧めします。

LOCAL_THIN_ARCHIVE

静的ライブラリをビルドするときに、この変数を true に設定します。この設定により、thin archive が生成されます。これは、オブジェクト ファイルを含まず、通常は含まれる実際のオブジェクトへのファイルパスだけを含むライブラリ ファイルです。

これはビルド出力のサイズを抑える際に有効です。この欠点は、こうしたライブラリを別の場所に移動できないということです(ライブラリ内のすべてのパスは相対パスです)。

有効な値は、truefalse、または空値です。既定値は Application.mk ファイルの APP_THIN_ARCHIVE 変数で指定できます。

: 非静的ライブラリ モジュールまたは事前にビルドされた静的ライブラリ モジュールの場合、これは無視されます。

LOCAL_FILTER_ASM

LOCAL_SRC_FILES に指定したファイルから抽出または生成するアセンブリ ファイルをフィルタリングするために、ビルドシステムが使用する shell コマンドとしてこの値を定義します。

この変数を定義すると、次の処理が発生します。

    1. ビルドシステムは、C ソースファイルまたは C++ ソースファイルをオブジェクト ファイルにコンパイルせずに、これらのファイルから一時的なアセンブリ ファイルを生成します。
    2. ビルドシステムは、一時的なアセンブリ ファイルと、LOCAL_SRC_FILES にリストされているアセンブリ ファイルの LOCAL_FILTER_ASM で shell コマンドを実行します。これにより、別の一時的なアセンブリ ファイルが生成されます。
    3. ビルドシステムはフィルタリングしたこれらのファイルをオブジェクト ファイルにコンパイルします。

次に例を示します。

LOCAL_SRC_FILES  := foo.c bar.S
LOCAL_FILTER_ASM :=

foo.c --1--> $OBJS_DIR/foo.S.original --2--> $OBJS_DIR/foo.S --3--> $OBJS_DIR/foo.o
bar.S                                 --2--> $OBJS_DIR/bar.S --3--> $OBJS_DIR/bar.o

「1」はコンパイラー、「2」はフィルタ、「3」はアセンブラに相当します。フィルタはスタンドアロンの shell コマンドで、入力ファイルの名前を第一引数、出力ファイルの名前を第二引数に取ります。 次に例を示します。

myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
myasmfilter bar.S $OBJS_DIR/bar.S

NDK がサポートするマクロ機能

このセクションでは、NDK が提供する GNU Make 機能のマクロについて説明します。$(call <function>) を使用してマクロを評価すると、テキスト情報が返されます。

my-dir

このマクロは、最後に組み込まれた Makefile のパスを返します。パスは通常、現在 Android.mk があるディレクトリです。my-dir は、Android.mk ファイルの先頭で LOCAL_PATH を定義するときに有用です。 次に例を示します。

LOCAL_PATH := $(call my-dir)

GNU Make の動作により、このマクロから実際に返されるのは、ビルド スクリプトの解析時にビルドシステムがインクルードした最終的な Makefile のパスとなります。 このため、別のファイルをインクルードしてから my-dir を呼び出さないようにしてください。

たとえば、次の例を考えてみましょう。

LOCAL_PATH := $(call my-dir)

# ... declare one module

include $(LOCAL_PATH)/foo/`Android.mk`

LOCAL_PATH := $(call my-dir)

# ... declare another module

ここでの問題は、my-dir の 2 回目の呼び出しで、LOCAL_PATH$PATH ではなく $PATH/foo として(指定された最新のインクルードなので)定義されるという点です。

Android.mk ファイルで、すべての要素のあとに追加のインクルードを配置することで、この問題を防ぐことができます。 次に例を示します。

LOCAL_PATH := $(call my-dir)

# ... declare one module

LOCAL_PATH := $(call my-dir)

# ... declare another module

# extra includes at the end of the Android.mk file
include $(LOCAL_PATH)/foo/Android.mk

この方法でファイルを構成することができない場合、最初の my-dir 呼び出しの値を別の変数に保存してください。 次に例を示します。

MY_LOCAL_PATH := $(call my-dir)

LOCAL_PATH := $(MY_LOCAL_PATH)

# ... declare one module

include $(LOCAL_PATH)/foo/`Android.mk`

LOCAL_PATH := $(MY_LOCAL_PATH)

# ... declare another module

all-subdir-makefiles

現在の my-dir パスのすべてのサブディレクトリに含まれる Android.mk ファイルの一覧を返します。

この機能を使用すると、深くネストされたソース ディレクトリ階層をビルドシステムに提供することができます。 既定では、NDK が検索できるのは、Android.mk ファイルが含まれているディレクトリ内のファイルだけです。

this-makefile

現在の Makefile のパス(ビルドシステムがこの関数を呼び出した場所を起点にしたもの)を戻します。

parent-makefile

インクルード ツリー内の呼び出し元の Makefile のパス(現在の Makefile を含む Makefile のパス)を戻します。

grand-parent-makefile

インクルード ツリー内の呼び出し元の呼び出し元の Makefile のパス(現在の Makefile を含む Makefile のパス)を戻します。

import-module

モジュールの Android.mk ファイルをモジュール名で検索してインクルードできる機能です。 代表的な例を次に示します。

$(call import-module,<name>)

この例では、ビルドシステムは NDK_MODULE_PATH 環境変数が参照しているディレクトリ一覧で <name> のタグが付けられているモジュールを検索し、そのモジュールの Android.mk ファイルを自動的にインクルードします。