64 ビット ビルドについて

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

ネイティブの静的ライブラリと共有ライブラリの場合、ビルド システムは、両方のアーキテクチャのバイナリをビルドするためのルールを設定します。製品構成 ( PRODUCT_PACKAGES ) は、依存関係グラフと共に、ビルドされてシステム イメージにインストールされるバイナリを決定します。

実行可能ファイルとアプリの場合、ビルド システムはデフォルトで 64 ビット バージョンのみをビルドしますが、この設定はグローバルなBoardConfig.mk変数またはモジュール スコープの変数でオーバーライドできます。

製品構成

BoardConfig.mkには、2 番目の CPU アーキテクチャと ABI を構成するための次の変数が含まれています。

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

build/target/board/generic_arm64/BoardConfig.mkで例を確認できます。

multilib ビルドでは、 PRODUCT_PACKAGESのモジュール名は、ビルド システムによって定義されている限り、32 ビットと 64 ビットの両方のバイナリをカバーします。依存関係によって取り込まれたライブラリの場合、32 ビット ライブラリは、別の 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変数をオーバーライドできます。

LOCAL_MULTILIBを次のいずれかに設定します。

  • "both"は、32 ビットと 64 ビットの両方をビルドします。
  • "32"は 32 ビットのみをビルドします。
  • "64"は 64 ビットのみをビルドします。
  • "first"は、最初のアーキテクチャ (32 ビット デバイスでは 32 ビット、64 ビット デバイスでは 64 ビット) のみをビルドします。
  • ""がデフォルトです。ビルド システムは、モジュール クラスと、 LOCAL_MODULE_TARGET_ARCHLOCAL_32_BIT_ONLYなどの他のLOCAL_変数に基づいて、ビルドするアーキテクチャを決定します。

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

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

これら 2 つの変数にはマイナーなバリエーションがあります。

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

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

特定のアーキテクチャのビルド フラグを設定するには、アーキテクチャ固有のLOCAL_変数を使用します。アーキテクチャ固有のLOCAL_変数は、アーキテクチャ サフィックスが付いた通常の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,

パスのインストール

以前は、 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
    インストール パスを指定します。

生成されたソース

マルチライブラリ ビルドで、ソース ファイルを$(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によって取得される場合、multilib ビルドで 32 ビットと 64 ビットの両方にビルドされます。

事前構築済み

multilib ビルドでは、 TARGET_ARCHを (またはTARGET_2ND_ARCHと一緒に) 使用して、ビルド済みのバイナリがターゲットとするアーキテクチャをビルド システムに伝えることはできません。代わりに、 LOCAL_変数LOCAL_MODULE_TARGET_ARCHまたはLOCAL_MODULE_UNSUPPORTED_TARGET_ARCHを使用してください。

これらの変数を使用すると、ビルド システムは、64 ビットの multilib ビルドで動作している場合でも、対応する 32 ビットのビルド済みバイナリを選択できます。

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

ODEX ファイルの生成

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