Comprender las compilaciones de 64 bits

El sistema de compilación admite la creación de archivos 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 .

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

Para ejecutables y aplicaciones, el sistema de compilación compila solo la versión de 64 bits de forma predeterminada, pero puede anular esta configuración con una variable BoardConfig.mk global o una variable de ámbito de 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

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

En una compilación multilib, los nombres de los módulos en PRODUCT_PACKAGES cubren los binarios de 32 y 64 bits, siempre que estén definidos por el sistema de compilación. Para las bibliotecas extraídas por dependencia, se instala una biblioteca de 32 bits solo si lo requiere otra biblioteca o ejecutable de 32 bits. Lo mismo es cierto para las bibliotecas de 64 bits.

Sin embargo, los nombres de los módulos en la línea de comando make solo cubren la versión de 64 bits. Por ejemplo, después de ejecutar lunch aosp_arm64-eng , make libc compile solo la libc de 64 bits. Para compilar la libc de 32 bits, debe ejecutar make libc_32 .

Definición de módulo en Android.mk

Puede usar la variable LOCAL_MULTILIB para configurar su compilación para 32 bits/64 bits y anular la variable global TARGET_PREFER_32_BIT .

Establezca LOCAL_MULTILIB en uno de los siguientes:

  • "both" compila tanto 32 bits como 64 bits.
  • "32" construye solo 32 bits.
  • "64" construye solo 64 bits.
  • compilaciones "first" solo para la primera arquitectura (32 bits en dispositivos de 32 bits y 64 bits en dispositivos de 64 bits).
  • "" es el valor predeterminado. El sistema de compilación decide qué arquitectura crear en función de la clase de módulo y otras variables LOCAL_ , como LOCAL_MODULE_TARGET_ARCH y LOCAL_32_BIT_ONLY .

Si desea construir su módulo para arquitecturas específicas, use las siguientes variables:

  • LOCAL_MODULE_TARGET_ARCH
    Establezca esta variable en una lista de arquitecturas, como arm x86 arm64 . Si la arquitectura que se está construyendo está en esa lista, el sistema de construcción incluye el módulo actual.
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
    Esta variable es lo opuesto a LOCAL_MODULE_TARGET_ARCH . Si la arquitectura que se está construyendo no está en esa lista, el sistema de construcción incluye 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 advierte si se omite el módulo actual debido a las arquitecturas enumeradas.

Para configurar indicadores de compilación para una arquitectura en particular, use las variables LOCAL_ específicas de la arquitectura. Una variable LOCAL_ específica de la 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,

Estas variables se aplican solo si actualmente se está construyendo un binario para esa arquitectura.

A veces es más fácil configurar banderas en función de si el binario se está construyendo actualmente para 32 bits o 64 bits. Utilice 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,

Instalación de un camino

Anteriormente, podía usar LOCAL_MODULE_PATH para instalar una biblioteca en una ubicación distinta a la predeterminada. Por ejemplo, LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw .

En una compilación multilib, use 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 construye un ejecutable tanto de 32 bits como de 64 bits, use una de las siguientes variables para distinguir la ruta de instalación:

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

fuentes generadas

En una compilación multilib, si genera archivos fuente en $(local-intermediates-dir) (o $(intermediates-dir-for) con variables explícitas), no funciona de manera confiable. Esto se debe a que las compilaciones de 32 y 64 bits requieren las fuentes intermedias generadas, pero $(local-intermediates-dir) solo apunta a uno de los dos directorios intermedios.

El sistema de compilación proporciona un directorio intermedio dedicado y compatible con múltiples bibliotecas para generar fuentes. Puede llamar a $(local-generated-sources-dir) o $(generated-sources-dir-for) para obtener la ruta del directorio. Sus usos son similares a $(local-intermediates-dir) y $(intermediates-dir-for) .

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

Preconstruidos

En una compilación multilib, no puede usar TARGET_ARCH (o junto con TARGET_2ND_ARCH ) para decirle al sistema de compilación a qué arquitectura apunta el binario preconstruido. En su lugar, utilice las variables LOCAL_ LOCAL_MODULE_TARGET_ARCH o LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH .

Con estas variables, el sistema de compilación puede elegir el binario precompilado de 32 bits correspondiente incluso si está trabajando en una compilación multilib de 64 bits.

Si desea utilizar la arquitectura elegida para calcular la ruta de origen del binario precompilado, llame a $(get-prebuilt-src-arch) .

Generación de archivos ODEX

Para dispositivos de 64 bits, generamos de forma predeterminada archivos ODEX de 32 y 64 bits para la imagen de arranque y cualquier biblioteca de Java. Para los APK, generamos ODEX de manera predeterminada solo para la arquitectura principal de 64 bits. Si una aplicación se iniciará en procesos de 32 y 64 bits, use LOCAL_MULTILIB := both para asegurarse de que se generen archivos ODEX de 32 y 64 bits. Si la aplicación tiene bibliotecas JNI de 32 o 64 bits, ese indicador también le indica al sistema de compilación que las incluya.