Use as informações nesta página para criar os makefiles para seu dispositivo e produto.
Cada novo módulo Android deve ter um arquivo de configuração para direcionar o sistema de compilação com metadados do módulo, dependências de tempo de compilação e instruções de empacotamento. O Android usa o sistema de compilação Soong . Consulte Compilando o Android para obter mais informações sobre o sistema de compilação do Android.
Entendendo as camadas de construção
A hierarquia de construção inclui as camadas de abstração que correspondem à composição física de um dispositivo. Essas camadas são descritas na tabela abaixo. Cada camada se relaciona com a que está acima dela em um relacionamento de um para muitos. Por exemplo, uma arquitetura pode ter mais de uma placa e cada placa pode ter mais de um produto. Você pode definir um elemento em uma determinada camada como uma especialização de um elemento na mesma camada, o que elimina a cópia e simplifica a manutenção.
Camada | Exemplo | Descrição |
---|---|---|
produtos | meuProduto, meuProduto_eu, meuProduto_eu_fr, j2, sdk | A camada do produto define a especificação do recurso de um produto de envio, como os módulos a serem construídos, os códigos de idioma suportados e a configuração para vários códigos de idioma. Em outras palavras, este é o nome do produto geral. As variáveis específicas do produto são definidas nos makefiles de definição do produto. Um produto pode herdar de outras definições de produto, o que simplifica a manutenção. Um método comum é criar um produto base que contém recursos que se aplicam a todos os produtos e, em seguida, criar variantes de produto com base nesse produto base. Por exemplo, dois produtos que diferem apenas por seus rádios (CDMA versus GSM) podem herdar do mesmo produto base que não define um rádio. |
Placa/dispositivo | marlim, linha azul, coral | A camada da placa/dispositivo representa a camada física de plástico no dispositivo (ou seja, o design industrial do dispositivo). Esta camada também representa os esquemas simples de um produto. Isso inclui os periféricos da placa e sua configuração. Os nomes usados são apenas códigos para diferentes configurações de placa/dispositivo. |
Arco | braço, x86, braço64, x86_64 | A camada de arquitetura descreve a configuração do processador e a interface binária do aplicativo (ABI) em execução na placa. |
Como usar variantes de compilação
Ao compilar para um produto específico, é útil ter pequenas variações na compilação da versão final. Em uma definição de módulo, o módulo pode especificar tags com LOCAL_MODULE_TAGS
, que podem ser um ou mais valores de optional
(default), debug
e eng
.
Se um módulo não especificar uma tag (por LOCAL_MODULE_TAGS
), sua tag padrão será optional
. Um módulo opcional é instalado somente se for exigido pela configuração do produto com PRODUCT_PACKAGES
.
Estas são as variantes de compilação atualmente definidas.
Variante | Descrição |
---|---|
eng | Este é o sabor padrão.
|
user | A variante destinada a ser os bits de lançamento final.
|
userdebug | O mesmo que user , com estas exceções:
|
Diretrizes para userdebug
A execução de builds de userdebug em testes ajuda os desenvolvedores de dispositivos a entender o desempenho e o poder das versões em desenvolvimento. Para manter a consistência entre as compilações do usuário e do userdebug e para obter métricas confiáveis nas compilações usadas para depuração, os desenvolvedores de dispositivos devem seguir estas diretrizes:
- userdebug é definido como uma compilação de usuário com acesso root habilitado, exceto:
- aplicativos somente de depuração do usuário que são executados apenas sob demanda pelo usuário
- Operações que são executadas apenas durante a manutenção ociosa (no carregador/carregado totalmente), como usar
dex2oatd
versusdex2oat
para compilações em segundo plano
- Não inclua recursos habilitados/desabilitados por padrão com base no tipo de compilação. Os desenvolvedores são desencorajados a usar qualquer forma de registro que afete a vida útil da bateria, como registro de depuração ou despejo de heap.
- Quaisquer recursos de depuração habilitados por padrão no userdebug devem ser claramente definidos e compartilhados com todos os desenvolvedores que trabalham no projeto. Você deve habilitar os recursos de depuração apenas por tempo limitado até que o problema que você está tentando depurar seja resolvido.
Personalizando a compilação com sobreposições de recursos
O sistema de compilação do Android usa sobreposições de recursos para personalizar um produto no momento da compilação. As sobreposições de recursos especificam arquivos de recursos que são aplicados sobre os padrões. Para usar sobreposições de recursos, modifique o arquivo de compilação do projeto para definir PRODUCT_PACKAGE_OVERLAYS
como um caminho relativo ao seu diretório de nível superior. Esse caminho se torna uma raiz sombra pesquisada junto com a raiz atual quando o sistema de compilação pesquisa recursos.
As configurações personalizadas mais comuns estão contidas no arquivo frameworks/base/core/res/res/values/config.xml .
Para configurar uma sobreposição de recurso neste arquivo, adicione o diretório de sobreposição ao arquivo de compilação do projeto usando um dos seguintes:
PRODUCT_PACKAGE_OVERLAYS := device/device-implementer/device-name/overlay
ou
PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay
Em seguida, adicione um arquivo de sobreposição ao diretório, por exemplo:
vendor/foobar/overlay/frameworks/base/core/res/res/values/config.xml
Quaisquer strings ou matrizes de strings encontradas no arquivo config.xml
de sobreposição substituem aquelas encontradas no arquivo original.
Construindo um produto
Você pode organizar os arquivos de origem do seu dispositivo de várias maneiras. Aqui está uma breve descrição de uma maneira de organizar uma implementação do Pixel.
Pixel é implementado com uma configuração de dispositivo principal chamada marlin
. A partir dessa configuração de dispositivo, um produto é criado com um makefile de definição de produto que declara informações específicas do produto sobre o dispositivo, como nome e modelo. Você pode ver o diretório device/google/marlin
para ver como tudo isso está configurado.
Escrevendo makefiles de produtos
As etapas a seguir descrevem como configurar os makefiles do produto de maneira semelhante à da linha de produtos Pixel:
- Crie um diretório
device/ <company-name> / <device-name>
para seu produto. Por exemplo,device/google/marlin
. Este diretório conterá o código-fonte do seu dispositivo junto com os makefiles para construí-los. - Crie um makefile
device.mk
que declare os arquivos e módulos necessários para o dispositivo. Para obter um exemplo, consultedevice/google/marlin/device-marlin.mk
. - Crie um makefile de definição de produto para criar um produto específico com base no dispositivo. O seguinte makefile foi retirado de
device/google/marlin/aosp_marlin.mk
como exemplo. Observe que o produto herda dos arquivosdevice/google/marlin/device-marlin.mk
evendor/google/marlin/device-vendor-marlin.mk
por meio do makefile, ao mesmo tempo em que declara as informações específicas do produto, como nome, marca, e modelo.# Inherit from the common Open Source product configuration $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk) $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk) PRODUCT_NAME := aosp_marlin PRODUCT_DEVICE := marlin PRODUCT_BRAND := Android PRODUCT_MODEL := AOSP on msm8996 PRODUCT_MANUFACTURER := Google PRODUCT_RESTRICT_VENDOR_FILES := true PRODUCT_COPY_FILES += device/google/marlin/fstab.common:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.marlin $(call inherit-product, device/google/marlin/device-marlin.mk) $(call inherit-product-if-exists, vendor/google_devices/marlin/device-vendor-marlin.mk) PRODUCT_PACKAGES += \ Launcher3QuickStep \ WallpaperPicker
Consulte Configurando variáveis de definição de produto para variáveis adicionais específicas do produto que você pode adicionar aos seus makefiles.
- Crie um arquivo
AndroidProducts.mk
que aponte para os makefiles do produto. Neste exemplo, apenas o makefile de definição do produto é necessário. O exemplo abaixo é dedevice/google/marlin/AndroidProducts.mk
(que contém marlin, o Pixel, e sailfish, o Pixel XL, que compartilhou a maioria das configurações):PRODUCT_MAKEFILES := \ $(LOCAL_DIR)/aosp_marlin.mk \ $(LOCAL_DIR)/aosp_sailfish.mk COMMON_LUNCH_CHOICES := \ aosp_marlin-userdebug \ aosp_sailfish-userdebug
- Crie um makefile
BoardConfig.mk
que contenha configurações específicas da placa. Para obter um exemplo, consultedevice/google/marlin/BoardConfig.mk
. - Somente para Android 9 e versões anteriores , crie um arquivo
vendorsetup.sh
para adicionar seu produto (uma "combinação de almoço") à versão juntamente com uma variante de versão separada por um traço. Por exemplo:add_lunch_combo <product-name>-userdebug
- Neste ponto, você pode criar mais variantes de produtos com base no mesmo dispositivo.
Como definir variáveis de definição de produto
As variáveis específicas do produto são definidas no makefile do produto. A tabela mostra algumas das variáveis mantidas em um arquivo de definição de produto.
Variável | Descrição | Exemplo |
---|---|---|
PRODUCT_AAPT_CONFIG | configurações do aapt para usar ao criar pacotes. | |
PRODUCT_BRAND | A marca (por exemplo, operadora) para a qual o software é personalizado, se houver. | |
PRODUCT_CHARACTERISTICS | características do aapt para permitir a adição de recursos específicos de variantes a um pacote. | tablet , nosdcard |
PRODUCT_COPY_FILES | Lista de palavras como source_path:destination_path . O arquivo no caminho de origem deve ser copiado para o caminho de destino ao construir este produto. As regras para as etapas de cópia são definidas em config/makefile . | |
PRODUCT_DEVICE | Nome do desenho industrial. Este também é o nome da placa, e o sistema de compilação o utiliza para localizar BoardConfig.mk . | tuna |
PRODUCT_LOCALES | Uma lista separada por espaços de código de idioma de duas letras, pares de códigos de país de duas letras que descrevem várias configurações para o usuário, como o idioma da interface do usuário e a formatação de hora, data e moeda. A primeira localidade listada em PRODUCT_LOCALES é usada como localidade padrão do produto. | en_GB , de_DE , es_ES , fr_CA |
PRODUCT_MANUFACTURER | Nome do fabricante. | acme |
PRODUCT_MODEL | Nome do produto final visível ao usuário final. | |
PRODUCT_NAME | Nome visível ao usuário final para o produto geral. Aparece na tela Configurações > Sobre . | |
PRODUCT_OTA_PUBLIC_KEYS | Lista de chaves públicas OTA (over-the-air) para o produto. | |
PRODUCT_PACKAGES | Lista dos APKs e módulos a serem instalados. | Contatos do calendário |
PRODUCT_PACKAGE_OVERLAYS | Indica se deve usar recursos padrão ou adicionar sobreposições específicas do produto. | vendor/acme/overlay |
PRODUCT_SYSTEM_PROPERTIES | Lista das atribuições de propriedades do sistema no formato "key=value" para a partição do sistema. As propriedades do sistema para outras partições podem ser definidas por meio de PRODUCT_<PARTITION>_PROPERTIES como em PRODUCT_VENDOR_PROPERTIES para a partição do fornecedor. Nomes de partição suportados: SYSTEM , SYSTEM_EXT , ODM , VENDOR e PRODUCT . |
Configurando o idioma padrão do sistema e o filtro de localidade
Use essas informações para configurar o idioma padrão e o filtro de localidade do sistema e, em seguida, habilite o filtro de localidade para um novo tipo de dispositivo.
Propriedades
Configure o idioma padrão e o filtro de localidade do sistema usando propriedades de sistema dedicadas:
-
ro.product.locale
: para definir a localidade padrão. Isso é definido inicialmente para a primeira localidade na variávelPRODUCT_LOCALES
; você pode substituir esse valor. (Para obter mais informações, consulte a tabela Configurando variáveis de definição de produto .) -
ro.localization.locale_filter
: para definir um filtro de localidade, usando uma expressão regular aplicada a nomes de localidade. Por exemplo:- Filtro inclusivo:
^(de-AT|de-DE|en|uk).*
- permite apenas alemão (variantes da Áustria e Alemanha), todas as variantes em inglês do inglês e ucraniano - Filtro exclusivo:
^(?!de-IT|es).*
- exclui alemão (variante Itália) e todas as variantes de espanhol.
- Filtro inclusivo:
Habilitando o filtro de localidade
Para ativar o filtro, defina o valor da cadeia de caracteres da propriedade do sistema ro.localization.locale_filter
.
Ao definir o valor da propriedade do filtro e o idioma padrão por meio de oem/oem.prop
durante a calibração de fábrica, você pode configurar restrições sem inserir o filtro na imagem do sistema. Você garante que essas propriedades sejam selecionadas da partição OEM adicionando-as à variável PRODUCT_OEM_PROPERTIES
conforme indicado abaixo:
# Delegation for OEM customization PRODUCT_OEM_PROPERTIES += \ ro.product.locale \ ro.localization.locale_filter
Então, na produção, os valores reais são gravados em oem/oem.prop
, para refletir os requisitos de destino. Com essa abordagem, os valores padrão são retidos durante a redefinição de fábrica, de modo que as configurações iniciais pareçam exatamente como uma primeira configuração para o usuário.
Configurando ADB_VENDOR_KEYS para conectar via USB
A variável de ambiente ADB_VENDOR_KEYS
permite que fabricantes de dispositivos acessem compilações depuráveis (-userdebug e -eng, mas não -user) sobre adb sem autorização manual. Normalmente, o adb gera uma chave de autenticação RSA exclusiva para cada computador cliente, que será enviada para qualquer dispositivo conectado. Esta é a chave RSA mostrada na caixa de diálogo de autorização do adb. Como alternativa, você pode criar chaves conhecidas na imagem do sistema e compartilhá-las com o cliente adb. Isso é útil para o desenvolvimento do SO e especialmente para testes, pois evita a necessidade de interagir manualmente com a caixa de diálogo de autorização do adb.
Para criar chaves de fornecedor, uma pessoa (geralmente um gerente de versão) deve:
- Gere um par de chaves usando
adb keygen
. Para dispositivos Google, o Google gera um novo par de chaves para cada nova versão do sistema operacional. - Verifique os pares de chaves, em algum lugar na árvore de origem. O Google os armazena em
vendor/google/security/adb/
, por exemplo. - Defina a variável de compilação
PRODUCT_ADB_KEYS
para apontar para seu diretório de chaves. O Google faz isso adicionando um arquivoAndroid.mk
no diretório de chaves que dizPRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub
, o que ajuda a garantir que nos lembremos de gerar um novo par de chaves para cada versão do SO.
Aqui está o makefile que o Google usa no diretório onde armazenamos nossos pares de chaves com check-in para cada versão:
PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub ifeq ($(wildcard $(PRODUCT_ADB_KEYS)),) $(warning ========================) $(warning The adb key for this release) $(warning ) $(warning $(PRODUCT_ADB_KEYS)) $(warning ) $(warning does not exist. Most likely PLATFORM_VERSION in build/core/version_defaults.mk) $(warning has changed and a new adb key needs to be generated.) $(warning ) $(warning Please run the following commands to create a new key:) $(warning ) $(warning make -j8 adb) $(warning LOGNAME=android-eng HOSTNAME=google.com adb keygen $(patsubst %.pub,%,$(PRODUCT_ADB_KEYS))) $(warning ) $(warning and upload/review/submit the changes) $(warning ========================) $(error done) endif
Para usar essas chaves de fornecedor, um engenheiro precisa apenas definir a variável de ambiente ADB_VENDOR_KEYS
para apontar para o diretório no qual os pares de chaves estão armazenados. Isso diz ao adb
para tentar essas chaves canônicas primeiro, antes de retornar à chave do host gerada que requer autorização manual. Quando o adb
não puder se conectar a um dispositivo não autorizado, a mensagem de erro sugerirá que você defina ADB_VENDOR_KEYS
se ainda não estiver definido.