Google は、黒人コミュニティに対する人種平等の促進に取り組んでいます。取り組みを見る

64 ビットビルドについて

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

ネイティブ静的ライブラリと共有ライブラリの場合、ビルドシステムでは、バイナリをビルドするためのルールが両方のアーキテクチャを対象にして設定されます。システム イメージにビルドおよびインストールされるバイナリは、プロダクト構成(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 ビルドの場合、32 ビットと 64 ビットの両方のバイナリがビルドシステムで定義されていれば、PRODUCT_PACKAGES のモジュール名にそれらのバイナリが含まれます。依存関係によって取り込まれたライブラリについては、別の 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_ 変数(LOCAL_MODULE_TARGET_ARCHLOCAL_32_BIT_ONLY など)に基づいてビルド対象のアーキテクチャを決定します。

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

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

生成されたソース

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_2ND_ARCH を併用)して、事前ビルドされたバイナリのターゲット アーキテクチャをビルドシステムに伝えることができません。代わりに、LOCAL_ 変数(LOCAL_MODULE_TARGET_ARCH または LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH)を使用します。

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

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

ODEX ファイルの生成

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