Sistema de construção Soong

Antes do lançamento do Android 7.0, o Android usava GNU Make exclusivamente para descrever e executar suas regras de construção. O sistema de compilação Make é amplamente suportado e usado, mas na escala do Android tornou-se lento, sujeito a erros, não escalonável e difícil de testar. O sistema de compilação Soong oferece a flexibilidade necessária para compilações Android.

Por esse motivo, espera-se que os desenvolvedores da plataforma mudem do Make e adotem o Soong o mais rápido possível. Envie perguntas ao Grupo do Google sobre construção de Android para receber suporte.

O que é Soong?

O sistema de compilação Soong foi introduzido no Android 7.0 (Nougat) para substituir o Make. Ele aproveita a ferramenta de clone Kati GNU Make e o componente do sistema de compilação Ninja para acelerar as compilações do Android.

Consulte a descrição do Android Make Build System no Android Open Source Project (AOSP) para obter instruções gerais e Build System Changes para Android.mk Writers para aprender sobre as modificações necessárias para se adaptar do Make ao Soong.

Consulte as entradas relacionadas à construção no glossário para obter definições de termos-chave e os arquivos de referência do Soong para obter detalhes completos.

Comparação entre Make e Soong

Aqui está uma comparação da configuração Make com Soong realizando o mesmo em um arquivo de configuração Soong (Blueprint ou .bp ).

Dê exemplo

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)

Um breve exemplo

cc_library_shared {
     name: "libxmlrpc++",

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

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

Para exemplos de configuração Soong específicos de teste, consulte Configuração de compilação simples .

Para obter uma explicação dos campos em um arquivo Android.bp, consulte Formato de arquivo Android.bp .

Módulos especiais

Alguns grupos de módulos especiais possuem características únicas.

Módulos padrão

Um módulo padrão pode ser usado para repetir as mesmas propriedades em vários módulos. Por exemplo:

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

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

Módulos pré-construídos

Alguns tipos de módulos pré-construídos permitem que um módulo tenha o mesmo nome que seus equivalentes baseados na fonte. Por exemplo, pode haver um cc_prebuilt_binary chamado foo quando já existe um cc_binary com o mesmo nome. Isso dá aos desenvolvedores a flexibilidade de escolher qual versão incluir em seu produto final. Se uma configuração de build contiver ambas as versões, o valor do sinalizador prefer na definição do módulo pré-construído determinará qual versão terá prioridade. Observe que alguns módulos pré-construídos têm nomes que não começam com prebuilt , como android_app_import .

Módulos de namespace

Até que o Android seja totalmente convertido de Make para Soong, a configuração do produto Make deverá especificar um valor PRODUCT_SOONG_NAMESPACES . Seu valor deve ser uma lista separada por espaço de namespaces que Soong exporta para Make para ser construída pelo comando m . Após a conclusão da conversão do Android para Soong, os detalhes de ativação de namespaces podem mudar.

Soong fornece a capacidade de módulos em diretórios diferentes especificarem o mesmo nome, desde que cada módulo seja declarado em um namespace separado. Um namespace pode ser declarado assim:

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

Observe que um namespace não possui uma propriedade name; seu caminho é automaticamente atribuído como seu nome.

Cada módulo Soong recebe um namespace com base em sua localização na árvore. Cada módulo Soong é considerado no namespace definido pelo soong_namespace encontrado em um arquivo Android.bp no diretório atual ou no diretório ancestral mais próximo. Se nenhum módulo soong_namespace for encontrado, o módulo será considerado no namespace raiz implícito.

Aqui está um exemplo: Soong tenta resolver a dependência D declarada pelo módulo M no namespace N que importa os namespaces I1, I2, I3…

  1. Então, se D for um nome totalmente qualificado no formato //namespace:module , apenas o namespace especificado será pesquisado pelo nome do módulo especificado.
  2. Caso contrário, Soong primeiro procura um módulo chamado D declarado no namespace N.
  3. Se esse módulo não existir, Soong procura um módulo chamado D nos namespaces I1, I2, I3…
  4. Por último, Soong procura no namespace raiz.