Cómo hacer conversiones de Make a Soong

Antes del lanzamiento de Android 7.0, Android usaba GNU Make de forma exclusiva para describir y ejecutar sus reglas de compilación. El sistema de compilación de Make se admite y utiliza ampliamente, pero, en la escala de Android, era lento y propenso a errores, no se podía escalar y era difícil probar. El sistema de compilación Soong ofrece la flexibilidad necesaria para las compilaciones de Android.

Por eso, se espera que los desarrolladores de la plataforma dejen de usar Make y adopten Soong lo antes posible. Para recibir asistencia, envía tus preguntas al Grupo de Google android-building.

¿Qué es Soong?

El sistema de compilación de Soong se introdujo en Android 7.0 (Nougat) para reemplazar a Make. Aprovecha la herramienta de clonación de GNU Make de Kati y el componente del sistema de compilación Ninja para acelerar las compilaciones de Android.

Consulta la descripción de Sistema de compilación de Make de Android en el Proyecto de código abierto de Android (AOSP) para obtener instrucciones generales. También consulta Cambios del sistema de compilación para los escritores de Android.mk para obtener información sobre las modificaciones necesarias para la adaptación de Make a Soong.

Para obtener más detalles, consulta las entradas relacionadas con la compilación en el glosario para conocer las definiciones de los términos clave y los archivos de referencia de Soong.

Comparación entre Make y Soong

A continuación, se muestra una comparación de una configuración de Make y una de Soong con los mismos resultados en un archivo de configuración de Soong (Blueprint o .bp).

Ejemplo de Make

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libxmlrpc++
LOCAL_MODULE_HOST_OS := linux

LOCAL_RTTI_FLAG := -frtti
LOCAL_CPPFLAGS := -Wall -Werror -fexceptions
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/src

LOCAL_SRC_FILES := $(call \
     all-cpp-files-under,src)
include $(BUILD_SHARED_LIBRARY)

Ejemplo de Soong

cc_library_shared {
     name: "libxmlrpc++",

     rtti: true,
     cppflags: [
           "-Wall",
           "-Werror",
           "-fexceptions",
     ],
     export_include_dirs: ["src"],
     srcs: ["src/**/*.cpp"],

     target: {
           darwin: {
                enabled: false,
           },
     },
}

Para obtener ejemplos de configuración de Soong específicos de la prueba, consulta Configuración de compilación simple.

Para obtener una explicación de los campos en un archivo Android.bp, consulta el formato de archivo de Android.bp.

Módulos especiales

Algunos grupos de módulos especiales tienen características únicas.

Módulos predeterminados

Un módulo predeterminado se puede usar para repetir las mismas propiedades en varios módulos. Por ejemplo:

cc_defaults {
    name: "gzip_defaults",
    shared_libs: ["libz"],
    stl: "none",
}

cc_binary {
    name: "gzip",
    defaults: ["gzip_defaults"],
    srcs: ["src/test/minigzip.c"],
}

Módulos compilados previamente

Algunos tipos de módulos compilados previamente permiten que un módulo tenga el mismo nombre que sus contrapartes basadas en la fuente. Por ejemplo, puede haber un cc_prebuilt_binary con el nombre foo cuando ya existe un cc_binary con el mismo nombre. Esto les brinda a los desarrolladores la flexibilidad de elegir qué versión incluir en el producto final. Si una configuración de compilación tiene ambas versiones, el valor de la marca de prefer en la definición del módulo compilado previamente determina la versión que tiene prioridad. Algunos módulos compilados previamente tienen nombres que no comienzan con prebuilt, como android_app_import.

Módulos de espacios de nombres

Hasta que Android complete la conversión de Make a Soong, la configuración de productos Make debe especificar un valor de PRODUCT_SOONG_NAMESPACES. El valor debe ser una lista de espacios de nombres separados por espacios que Soong exporta a Make para que el comando m la compile. Una vez que se complete la conversión a Soong de Android, podrían cambiar los detalles de habilitación de los espacios de nombres.

Soong permite que módulos en directorios diferentes especifiquen el mismo nombre, siempre que cada módulo se declare en un espacio de nombres por separado. Un espacio de nombres se puede declarar de la siguiente manera:

soong_namespace {
    imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
}

Un espacio de nombres no tiene una propiedad de nombre, sino que se asigna automáticamente la ruta de acceso como su nombre.

Se asigna un espacio de nombres a cada módulo de Soong en función de la ubicación en el árbol. Se considera que cada módulo de Soong está en el espacio de nombres definido por el soong_namespace que se encuentra en un archivo Android.bp en el directorio actual o en el directorio principal más cercano. Si no se encuentra dicho módulo de soong_namespace, se considera que el módulo está en el espacio de nombres de raíz implícito.

Por ejemplo: Soong intenta resolver una dependencia D declarada por el módulo M en el espacio de nombres N que importa los espacios de nombres I1, I2, I3…

  1. Por lo tanto, si D es un nombre completamente calificado del //namespace:module de forma, solo se busca el nombre del módulo especificado en el espacio de nombres indicado.
  2. De lo contrario, Soong primero busca un módulo con el nombre D declarado en el espacio de nombres N.
  3. Si no existe ese módulo, Soong busca un módulo con el nombre D en los espacios de nombres I1, I2, I3…
  4. Por último, Soong busca en el espacio de nombres de raíz.