Google is committed to advancing racial equity for Black communities. See how.

Información sobre las compilaciones de 64 bits

El sistema de compilación permite compilar objetos binarios para dos arquitecturas de CPU de destino (64 bits y 32 bits) en la misma compilación. Esto se conoce como compilación multilib.

En el caso de las bibliotecas nativas estáticas y las bibliotecas compartidas, el sistema de compilación configura reglas de compilación de objetos binarios para ambas arquitecturas. La configuración del producto (PRODUCT_PACKAGES), junto con el gráfico de dependencia, determina qué objetos binarios se compilan y se instalan en la imagen del sistema.

En el caso de los ejecutables y las apps, el sistema de compilación solo compila la versión de 64 bits de forma predeterminada. Sin embargo, puedes anular esta configuración con una variable BoardConfig.mk global o una variable específica del módulo.

Configuración del producto

BoardConfig.mk incluye las siguientes variables para configurar la segunda arquitectura de CPU y ABI:

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

Puedes ver un ejemplo en build/target/board/generic_arm64/BoardConfig.mk.

En una compilación multilib, los nombres de módulos en PRODUCT_PACKAGES abarcan los objetos binarios para 32 y 64 bits, siempre y cuando los defina el sistema de compilación. En el caso de las bibliotecas que extrae una dependencia, solo se instala una biblioteca de 32 bits si así lo requiere otra biblioteca de 32 bits o un archivo ejecutable. Lo mismo sucede con las bibliotecas de 64 bits.

No obstante, solo se aplican los nombres de módulo en la línea de comandos make a la versión de 64 bits. Por ejemplo, luego de ejecutar lunch aosp_arm64-eng, make libc solo compila la libc de 64 bits. Si quieres compilar la de 32 bits, debes ejecutar make libc_32.

Definición del módulo en Android.mk

Puedes usar la variable LOCAL_MULTILIB a fin de configurar tu compilación para 32 o 64 bits y anular la variable TARGET_PREFER_32_BIT global.

Configura LOCAL_MULTILIB en uno de los siguientes valores:

  • "both" compila 32 bits y 64 bits.
  • "32" solo compila 32 bits.
  • "64" solo compila 64 bits.
  • "first" solo compila para la primera arquitectura (32 bits en dispositivos de 32 bits y 64 bits en dispositivos de 64 bits).
  • "" es la configuración predeterminada. El sistema de compilación decide qué arquitectura compilar en función de la clase del módulo y otras variables LOCAL_, como LOCAL_MODULE_TARGET_ARCH y LOCAL_32_BIT_ONLY.

Si deseas compilar tu módulo para arquitecturas específicas, usa las siguientes variables:

  • LOCAL_MODULE_TARGET_ARCH
    Establece esta variable como una lista de arquitecturas. Por ejemplo, arm x86 arm64. Si la arquitectura que se compila está en esa lista, el sistema de compilación actual incluirá el módulo actual.
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
    Esta variable es opuesta a LOCAL_MODULE_TARGET_ARCH. Si esa lista no contiene la arquitectura que se compilará, el sistema de compilación actual incluirá el módulo actual.

Hay variantes menores de estas dos variables:

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

El sistema de compilación muestra una advertencia si se omite el módulo actual debido a las arquitecturas de la lista.

Si quieres configurar marcas de compilación para una arquitectura en particular, usa las variables LOCAL_ específicas de la arquitectura. Una variable LOCAL_ específica de una arquitectura es una variable LOCAL_ normal con un sufijo de arquitectura, por ejemplo:

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

Solo se aplican estas variables si actualmente se está compilando un objeto binario para esa arquitectura.

En ocasiones, es más sencillo configurar marcas en función de si el objeto binario se compila para 32 o 64 bits. Usa la variable LOCAL_ con un sufijo _32 o _64, por ejemplo:

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

Cómo instalar una ruta de acceso

Antes, se podía usar LOCAL_MODULE_PATH para instalar una biblioteca en una ubicación que no fuera la predeterminada. Por ejemplo, LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw.

En una compilación multilib, usa LOCAL_MODULE_RELATIVE_PATH en su lugar:

LOCAL_MODULE_RELATIVE_PATH := hw

Con este formato, tanto las bibliotecas de 64 bits como las de 32 bits se instalan en el lugar correcto.

Si compilas un archivo ejecutable para 32 bits y 64 bits, usa una de las siguientes variables a fin de distinguir la ruta de acceso de instalación:

  • LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64
    Especifica el nombre del archivo instalado.
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64
    Especifica la ruta de acceso de instalación.

Fuentes generadas

En una compilación multilib, si generas archivos de origen en $(local-intermediates-dir) (o $(intermediates-dir-for) con variables explícitas), el funcionamiento no es confiable, ya que tanto la compilación de 32 bits como la de 64 bits requieren los archivos de origen intermedios generados, pero $(local-intermediates-dir) solo apunta a uno de los dos directorios intermedios.

El sistema de compilación proporciona un directorio intermedio dedicado que es compatible con multilib para generar fuentes. Puedes llamar a $(local-generated-sources-dir) o $(generated-sources-dir-for) a fin de obtener la ruta de acceso al directorio. Sus usos son similares a $(local-intermediates-dir) y $(intermediates-dir-for).

Si se genera un archivo de origen en este directorio dedicado y LOCAL_GENERATED_SOURCES lo recoge, se compila para 32 y 64 bits en una compilación multilib.

Compilaciones previas

En una compilación multilib, no puedes usar TARGET_ARCH (ni junto con TARGET_2ND_ARCH) para indicarle al sistema de compilación a qué arquitectura se orienta el objeto binario precompilado. En su lugar, usa las variables LOCAL_ LOCAL_MODULE_TARGET_ARCH o LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH.

Con esas variables, el sistema de compilación puede elegir el objeto binario de 32 bits precompilado correspondiente, incluso aunque funcione en una compilación multilib de 64 bits.

Si deseas usar la arquitectura elegida para calcular la ruta de acceso de origen del objeto binario precompilado, llama a $(get-prebuilt-src-arch).

Generación de archivos ODEX

En el caso de dispositivos de 64 bits, de forma predeterminada, generamos archivos ODEX de 32 y 64 bits para la imagen de inicio y cualquier biblioteca Java. En el caso de los APK, de forma predeterminada, generamos archivos ODEX solo para la arquitectura principal de 64 bits. Si se iniciará una app en procesos de 32 y 64 bits, usa LOCAL_MULTILIB := both a fin de garantizar que se generen archivos ODEX para ambas arquitecturas. Si la app tiene bibliotecas JNI de 32 o 64 bits, esa marca también le indica al sistema de compilación que las incluya.