Android.mk

このページでは、ndk-build が使用する Android.mk ビルドファイルの構文について説明します。

概要

Android.mk ファイルは、プロジェクトの jni/ ディレクトリのサブディレクトリにあり、ビルドシステム向けのソースと共有ライブラリが記述されています。このファイルは、実際には GNU Makefile のごく一部であり、ビルドシステムによって 1 回または複数回解析されます。Android.mk ファイルは、Application.mk や、ビルドシステム、環境変数で定義されていないプロジェクト レベルの設定を定義する際に便利です。また、特定のモジュールを対象に、プロジェクト レベルの設定をオーバーライドすることもできます。

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

ビルドシステムは、ライブラリのパッケージ化に加えて、さまざまな処理を自動的に行います。たとえば、ヘッダー ファイルや、生成ファイル間の明示的な依存関係のリストを Android.mk ファイルに記載する必要はありません。このような関係は、NDK ビルドシステムが自動で計算します。そのため、将来の NDK リリースで新しいツールチェーンやプラットフォームがサポートされるようになったときでも、Android.mk ファイルを手動で編集する必要はありません。

このファイルの構文は、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_XXX 変数(LOCAL_MODULELOCAL_SRC_FILESLOCAL_STATIC_LIBRARIES など)を自動的にクリアする特殊な GNU Makefile をポイントします。ただし、LOCAL_PATH だけはクリアされません。システムは、すべての変数がグローバル変数となる単一の GNU Make 実行コンテキストで、すべてのビルド コントロール ファイルを解析します。そのため、この変数だけは値を保持する必要があります。各モジュールについて記述する前に、この変数を宣言(再宣言)する必要があります。

次に、ビルドするモジュールの名前を LOCAL_MODULE 変数に格納します。この変数は、アプリ内のモジュールごとに 1 回ずつ使用してください。

LOCAL_MODULE := hello-jni
    

モジュール名はそれぞれ一意でなければならず、スペースは使用できません。ビルドシステムは、最終版の共有ライブラリ ファイルを生成すると、LOCAL_MODULE に割り当てられている名前に対して適切なプレフィックスとサフィックスを自動的に付加します。たとえば、上記の例の場合、libhello-jni.so というライブラリが生成されます。

次の行で、ソースファイルを指定します。ファイルが複数ある場合はスペースで区切ります。

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 ファイルも用意されていますので、そちらもご覧ください。また、サンプル内の Android.mk ファイルの詳細については、サンプル: native-activity をご覧ください。このセクションで扱った変数の詳細については、次の変数とマクロをご覧ください。

変数とマクロ

ビルドシステムには、Android.mk ファイルで使用できる変数が数多く用意されています。大半の変数には、あらかじめ値が割り当てられています。値が割り当てられていない場合は、手動で値を割り当てることができます。

用意されている変数に加えて、独自の変数を定義することもできます。ただし、NDK ビルドシステムでは、次の変数名が予約済みとなっています。

  • LOCAL_ で始まる名前。LOCAL_MODULE など。
  • 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 と同様の変数で、ビルド済み静的ライブラリを対象とします。ビルド済みライブラリの使用方法については、ビルド済みライブラリを使用するをご覧ください。

ターゲット情報変数

ビルドシステムは、APP_ABI 変数(通常は、Application.mk ファイルで定義される)によって指定された ABI ごとに 1 回ずつ、Android.mk を解析します。APP_ABIall の場合、NDK がサポートしている ABI ごとに 1 回ずつ、ビルドシステムが Android.mk を解析します。このセクションでは、Android.mk を解析するたびにビルドシステムが定義する変数について説明します。

TARGET_ARCH

ビルドシステムがこの Android.mk ファイルを解析する際にターゲットとなる CPU ファミリー。この変数は、armarm64x86x86_64 のいずれかです。

TARGET_PLATFORM

ビルドシステムがこの Android.mk ファイルを解析する際にターゲットとなる Android API レベル番号。たとえば、Android 5.1 システム イメージは、Android API レベル 22(android-22)に対応します。プラットフォーム名と、対応する Android システム イメージのリストについては、Android NDK ネイティブ API をご覧ください。この変数を使用するための構文は次のとおりです。

ifeq ($(TARGET_PLATFORM),android-22)
        # ... do something ...
    endif
    

TARGET_ARCH_ABI

ビルドシステムがこの Android.mk ファイルを解析する際にターゲットとなる ABI。サポート対象の各 CPU とアーキテクチャに使用される ABI 設定を表 1 に示します。

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

CPU とアーキテクチャ 設定
ARMv7 armeabi-v7a
ARMv8 AArch64 arm64-v8a
i686 x86
x86-64 x86_64

CPU と ABI の組み合わせのターゲットとして ARMv8 AArch64 を指定する方法は次のとおりです。

ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
      # ... do something ...
    endif
    

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

今後も、別の値の新しいターゲット ABI が随時用意されていく予定です。

TARGET_ABI

ターゲットとなる Android API レベルと ABI を連結したもの。これは特に、実際のデバイスを想定して、特定のターゲット システム イメージを対象にテストを実施する場合に便利です。たとえば、Android API レベル 22 を搭載した 64 ビット ARM デバイスをチェックする場合は、次のように指定します。

ifeq ($(TARGET_ABI),android-22-arm64-v8a)
      # ... do something ...
    endif
    

モジュール記述変数

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

  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 ファイルを移植しやすくなります。

LOCAL_CPP_EXTENSION

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

LOCAL_CPP_EXTENSION := .cxx
    

この変数では、複数の拡張子を指定することができます。たとえば、次のようになります。

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)/<subdirectory>/foo
    

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

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

LOCAL_CFLAGS

必要に応じてこの変数を使用することで、C / C++ ソースファイルのビルド時にビルドシステムが渡すコンパイラ フラグを設定することができます。この機能は、マクロ定義やコンパイル設定を追加指定する際に役に立ちます。C++ 専用のフラグを指定する場合は、LOCAL_CPPFLAGS を使用します。

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

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

LOCAL_CFLAGS += -I<path>,
    

ただし、この目的のためには LOCAL_C_INCLUDES を使用することをおすすめします。こちらの方法であれば、ndk-gdb を使用したネイティブ デバッグでも、パスを利用できるようになります。

LOCAL_CPPFLAGS

ビルド対象が C++ ソースファイルだけの場合に渡されるコンパイラ フラグのセットで、必要に応じて指定します。コンパイラのコマンドラインでは、LOCAL_CFLAGS の後に配置されます。C と C++ 両方のフラグを指定する場合は、LOCAL_CFLAGS を使用します。

LOCAL_STATIC_LIBRARIES

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

現在のモジュールが共有ライブラリまたは実行ファイルの場合、この変数は、生成されたバイナリに対して自動的に依存先ライブラリをリンクします。

現在のモジュールが静的ライブラリの場合、この変数は、現在のモジュールに依存している他のモジュールもリスト内の依存先ライブラリに依存することを示すだけで、リンクは行いません。

LOCAL_SHARED_LIBRARIES

この変数は、このモジュールが実行時に依存する共有ライブラリのモジュールのリストを格納します。この情報は、リンク時に、対応する情報を生成ファイル内に埋め込む際に必要になります。

LOCAL_WHOLE_STATIC_LIBRARIES

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

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

LOCAL_LDLIBS

この変数は、共有ライブラリまたは実行ファイルをビルドする際に使用する追加リンカーフラグのリストを格納します。特定のシステム ライブラリ名を渡すには、-l プレフィックスを使用します。読み込み時に /system/lib/libz.so にリンクするモジュールを生成するようリンカーに指示するには、次のように指定します。

LOCAL_LDLIBS := -lz
    

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

LOCAL_LDFLAGS

共有ライブラリまたは実行ファイルをビルドする際にビルドシステムが使用する他のリンカーフラグのリストを格納します。たとえば、ARM/X86 で ld.bfd リンカーを使用するには、次のように指定します。

LOCAL_LDFLAGS += -fuse-ld=bfd
    

LOCAL_ALLOW_UNDEFINED_SYMBOLS

デフォルトでは、ビルドシステムが共有ライブラリをビルドする際に未定義の参照が検出されると、「undefined symbol」のエラーがスローされます。このエラーは、ソースコード内のバグを検出するうえで役に立ちます。

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

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
    

LOCAL_ARM_NEON

この変数が影響するのは、armeabi-v7a ABI をターゲットとしている場合に限られます。この変数を使用すると、C / C++ ソースファイル内で ARM Advanced SIMD(NEON)コンパイラ イントリンシクスを使用し、アセンブリ ファイル内で NEON 命令を使用できるようになります。

必ずしもすべての 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_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 にも依存していることになります。zoo は、foo からエクスポートされるすべてのフラグを継承することになります。

なお、ビルドシステムは、ローカルでビルドを行っている間(フラグをエクスポート中のモジュールをビルドしている間)は、エクスポート フラグを使用しません。そのため、上記の例の場合、ビルドシステムは、foo/foo.c をビルドしている間は -DFOO=1 をコンパイラに渡しません。ローカルでビルドする場合は、代わりに LOCAL_CFLAGS を使用してください。

LOCAL_EXPORT_CPPFLAGS

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

LOCAL_EXPORT_C_INCLUDES

この変数は LOCAL_EXPORT_CFLAGS と同様ですが、C インクルード パス用です。たとえば、bar.cfoo モジュールからヘッダーをインクルードする必要がある場合などに役に立ちます。

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 の場合に特に役に立ちます。Windows では、コマンドラインの許容文字数が最大 8,191 文字であり、複雑なプロジェクトでは文字数が足りなくなる可能性があります。また、この機能は、リストファイル内にほぼすべてのコンパイラ フラグを配置している個々のソースファイルのコンパイルにも効果があります。

true 以外の値の場合、デフォルト動作に戻されます。また、Application.mk ファイル内で APP_SHORT_COMMANDS を定義すると、プロジェクト内のすべてのモジュールを対象にして、自動的に動作を指定できます。

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

LOCAL_THIN_ARCHIVE

静的ライブラリをビルドする場合は、この変数を true に設定します。この設定により、シンアーカイブが生成されます。シンアーカイブは、オブジェクト ファイルを含まずに、代わりに、実際のオブジェクトへのファイルパスだけを含むライブラリ ファイルです。

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

有効な値は、truefalse、空欄です。Application.mk ファイル内の APP_THIN_ARCHIVE 変数で、デフォルト値を指定できます。

LOCAL_FILTER_ASM

この変数は、LOCAL_SRC_FILES で指定したファイルからアセンブリ ファイルの抽出や生成を行う際、ビルドシステムがフィルタリング用に使用するシェルコマンドを定義します。この変数を定義すると、次の処理が発生します。

  1. ビルドシステムは、C / C++ ソースファイルをオブジェクト ファイルにコンパイルせずに、ソースファイルから一時的なアセンブリ ファイルを生成します。
  2. ビルドシステムは、一時的アセンブリ ファイルと、LOCAL_SRC_FILES 内のリストにあるアセンブリ ファイルに対して、LOCAL_FILTER_ASM 内のシェルコマンドを実行します。これにより、別の一時的アセンブリ ファイルが生成されます。
  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」はアセンブラに相当します。フィルタはスタンドアロンのシェルコマンドで、入力ファイルの名前を第 1 引数に取り、出力ファイルの名前を第 2 引数に取ります。たとえば、次のようになります。

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 ファイルを自動的にインクルードします。