32 ビットおよび 64 ビット アーキテクチャのビルド

ビルドシステムは、同じビルド内での 2 つのターゲット CPU アーキテクチャ(32 ビットと 64 ビット)のバイナリビルドをサポートしています。この 2 つのターゲットのビルドは「multilib ビルド」と呼ばれています。

組み込みの静的ライブラリと共有ライブラリの場合、ビルドシステムでは、バイナリをビルドするためのルールが両方のアーキテクチャを対象にして設定されます。システム イメージにビルドおよびインストールされるバイナリは、プロダクト構成(PRODUCT_PACKAGES)と依存関係グラフから決定されます。

実行可能ファイルとアプリに関しては、デフォルトでは 64 ビット バージョンだけがビルドされますが、BoardConfig.mk グローバル変数またはモジュール スコープ変数を使用することで、この設定をオーバーライドできます。

2 番目の CPU アーキテクチャと ABI を指定する

BoardConfig.mk には、2 番目の CPU アーキテクチャとアプリケーション バイナリ インターフェース(ABI)を構成するための以下の変数が含まれています。

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

これらの変数を使用する makefile の例については、build/make/target/board/generic_arm64/BoardConfig.mk をご覧ください。

multilib ビルドの場合、32 ビットと 64 ビットの両方のバイナリがビルドシステムで定義されていれば、PRODUCT_PACKAGES のモジュール名にそれらのバイナリが含まれます。依存関係によって含まれるライブラリについては、別の 32 ビットまたは 64 ビットのライブラリまたは実行可能ファイルで必要とされる場合にのみ、32 ビットまたは 64 ビットのライブラリがインストールされます。

ただし、make コマンドラインのモジュール名は、64 ビット バージョンのみを対象としています。たとえば、lunch aosp_arm64-eng の実行後、make libc は 64 ビットの libc のみをビルドします。32 ビットの libc をビルドするには、make libc_32 を実行する必要があります。

Android.mk でモジュール アーキテクチャを定義する

LOCAL_MULTILIB 変数を使用して 32 ビットと 64 ビットのビルドを構成し、TARGET_PREFER_32_BIT グローバル変数をオーバーライドすることができます。

TARGET_PREFER_32_BIT をオーバーライドするには、LOCAL_MULTILIB を次のいずれかに設定します。

  • both: 32 ビットと 64 ビットの両方をビルドします。
  • 32: 32 ビットのみをビルドします。
  • 64: 64 ビットのみをビルドします。
  • first: 最初のアーキテクチャ(32 ビットデバイスでは 32 ビット、64 ビットデバイスでは 64 ビット)のみをビルドします。

デフォルトでは LOCAL_MULTILIB は設定されておらず、ビルドシステムはモジュール クラスと他の LOCAL_* 変数(LOCAL_MODULE_TARGET_ARCHLOCAL_32_BIT_ONLY など)に基づいて、ビルドするアーキテクチャを決定します。

特定のアーキテクチャのモジュールをビルドする場合は、以下の変数を使用します。

  • LOCAL_MODULE_TARGET_ARCH - この変数にはアーキテクチャのリスト(arm x86 arm64 など)を設定します。ビルド中のアーキテクチャがこのリストに含まれている場合、ビルドシステムは現在のモジュールを対象に含めます。

  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH - これは LOCAL_MODULE_TARGET_ARCH と逆の変数です。ビルド中のアーキテクチャがこのリストに含まれてない場合(not)、ビルドシステムは現在のモジュールを対象に含めます。

この 2 つの変数には以下のマイナー バリアントがあります。

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

リストされているアーキテクチャが原因で現在のモジュールがスキップされた場合、ビルドシステムによって警告が表示されます。

特定のアーキテクチャ用にビルドフラグを設定するには、アーキテクチャ固有の LOCAL_* 変数を使用します。* はアーキテクチャ固有のサフィックスです。以下に例を示します。

  • LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,
  • LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,
  • LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,

これらの変数は、サフィックスで示されたアーキテクチャのバイナリがビルドされている場合にのみ適用されます。

ビルド中のバイナリが 32 ビットか 64 ビットかに基づいてフラグを設定するほうが簡単な場合もあります。LOCAL_* 変数は、_32 または _64 サフィックスを付加して使用します。以下に例を示します。

  • LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,
  • LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,
  • LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,

ライブラリのインストール パスを設定する

multilib 以外のビルドの場合は、LOCAL_MODULE_PATH を使用して、ライブラリをデフォルト以外の場所にインストールすることができます(例: LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw)。

一方、multilib ビルドでは、代わりに LOCAL_MODULE_RELATIVE_PATH を使用します。

LOCAL_MODULE_RELATIVE_PATH := hw

この形式を使用すると、64 ビットと 32 ビットの両方のライブラリを適切な場所にインストールできます。

32 ビットと 64 ビットの両方の実行可能ファイルをビルドする場合は、次のいずれかの変数を使用してインストール パスを区別します。

  • LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64 - インストール ファイル名を指定します。
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64 - インストール パスを指定します。

ソースファイルの中間ディレクトリを取得する

multilib ビルドでは、ソースファイルを $(local-intermediates-dir) に生成するか、明示的な変数を使用して $(intermediates-dir-for) に生成すると、動作が保証されなくなります。これは、中間生成されたソースが 32 ビットと 64 ビットの両方のビルドで必要になるにもかかわらず、$(local-intermediates-dir) が 2 つの中間ディレクトリの 1 つしか指定していないことが原因です。

ビルドシステムには、multilib に対応した専用の中間ディレクトリがソースの生成用に用意されています。中間ディレクトリのパスを取得するには、$(local-generated-sources-dir) または $(generated-sources-dir-for) マクロを使用します。これらのマクロの使い方は $(local-intermediates-dir) および $(intermediates-dir-for) と同様です。

ソースファイルがこの専用ディレクトリに生成され、LOCAL_GENERATED_SOURCES によって選択されると、32 ビットと 64 ビットの両方が multilib ビルドでビルドされます。

事前ビルドバイナリのターゲットのシステム アーキテクチャを指定する

multilib ビルドでは、TARGET_ARCH を使用(または TARGET_ARCHTARGET_2ND_ARCH を併用)して、事前ビルドバイナリのターゲットのシステム アーキテクチャを指定することができません。代わりに、LOCAL_* 変数(LOCAL_MODULE_TARGET_ARCH または LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH)を使用します。

これらの変数を使用することで、ビルドシステムは、64 ビットの multilib ビルドの実行中であっても、対応する 32 ビットの事前ビルドバイナリを選択できます。

選択したアーキテクチャを使用して、事前ビルドされたバイナリのソースパスを計算する場合は、$(get-prebuilt-src-arch) を呼び出します。

32 ビットおよび 64 ビット ODEX ファイルを確実に生成する

64 ビットデバイスでは、ブートイメージ用の 32 ビットおよび 64 ビット ODEX ファイルと Java ライブラリがデフォルトで生成されます。APK では、64 ビットのプライマリ アーキテクチャに対してのみ ODEX がデフォルトで生成されます。32 ビットプロセスと 64 ビットプロセスの両方でアプリを起動する場合は、LOCAL_MULTILIB := both を使用して、32 ビットと 64 ビットの両方の ODEX ファイルが生成されるようにします。アプリで 32 ビットまたは 64 ビットの JNI ライブラリを使用する場合も、このフラグによって JNI ライブラリをインクルードするようにビルドシステムに指示します。