Use as informações nesta página para criar 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 Construindo o Android para obter mais informações sobre o sistema de compilação do Android.
Entenda 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 aquela acima em um relacionamento 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 de produto define a especificação de recursos de um produto enviado, como os módulos a serem construídos, localidades suportadas e configuração para diversas localidades. Em outras palavras, este é o nome do produto geral. Variáveis específicas do produto são definidas em makefiles de definição de produto. Um produto pode herdar definições de outros produtos, o que simplifica a manutenção. Um método comum é criar um produto base que contenha 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 em seus rádios (CDMA versus GSM) podem herdar o mesmo produto base que não define um rádio. |
Placa/dispositivo | marlim, linha azul, coral | A camada placa/dispositivo representa a camada física de plástico do dispositivo (ou seja, o design industrial do dispositivo). Esta camada também representa os esquemas básicos de um produto. Isso inclui os periféricos da placa e sua configuração. Os nomes usados são meramente 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. |
Use variantes de compilação
Ao construir para um produto específico, é útil ter pequenas variações na 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
(padrão), debug
e eng
.
Se um módulo não especificar uma tag (por LOCAL_MODULE_TAGS
), sua tag será padronizada como optional
. Um módulo opcional será instalado somente se for exigido pela configuração do produto com PRODUCT_PACKAGES
.
Estas são as variantes de construção atualmente definidas.
Variante | Descrição |
---|---|
eng | Este é o sabor padrão.
|
user | A variante pretendia ser os bits finais do lançamento.
|
userdebug | O mesmo que user , com estas exceções:
|
Diretrizes para userdebug
A execução de compilações userdebug em testes ajuda os desenvolvedores de dispositivos a compreender o desempenho e o poder das versões em desenvolvimento. Para manter a consistência entre as compilações user e userdebug e para obter métricas confiáveis em 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 userdebug que são executados apenas sob demanda do usuário
- Operações que são executadas apenas durante a manutenção ociosa (no carregador/totalmente carregado), como usar
dex2oatd
versusdex2oat
para compilações em segundo plano
- Não inclua recursos habilitados/desabilitados por padrão com base no tipo de build. Os desenvolvedores são desencorajados de 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 ativar os recursos de depuração apenas por tempo limitado até que o problema que você está tentando depurar seja resolvido.
Personalize a construçã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 buildfile 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 procura recursos.
As configurações customizadas mais comumente estão contidas no arquivo frameworks/base/core/res/res/values/config.xml .
Para configurar uma sobreposição de recursos neste arquivo, adicione o diretório de sobreposição ao buildfile 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 sequências ou matrizes de sequências encontradas no arquivo config.xml
de sobreposição substituem aquelas encontradas no arquivo original.
Construa um produto
Você pode organizar os arquivos de origem do seu dispositivo de muitas maneiras diferentes. 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 visualizar o diretório device/google/marlin
para ver como tudo isso está configurado.
Escreva makefiles de produtos
As etapas a seguir descrevem como configurar makefiles de produtos de maneira semelhante à 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. Por 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 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 podem ser incluídas em 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 compartilhava a maior parte 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. Por 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") ao build junto com uma variante de build 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.
Definir variáveis de definição de produto
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 aapt para usar ao criar pacotes. | |
PRODUCT_BRAND | A marca (por exemplo, operadora) para a qual o software é personalizado. | |
PRODUCT_CHARACTERISTICS | características aapt para permitir a adição de recursos específicos de variante 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ódigos de idioma de duas letras e pares de códigos de país de duas letras que descrevem diversas configurações para o usuário, como o idioma da interface do usuário e a formatação de hora, data e moeda. O primeiro código de idioma listado em PRODUCT_LOCALES é usado como código de idioma padrão do produto. | en_GB , de_DE , es_ES , fr_CA |
PRODUCT_MANUFACTURER | Nome do fabricante. | acme |
PRODUCT_MODEL | Nome visível para o usuário final do produto final. | |
PRODUCT_NAME | Nome visível para o usuário final do produto geral. Aparece na tela Configurações > Sobre . | |
PRODUCT_OTA_PUBLIC_KEYS | Lista de chaves públicas over-the-air (OTA) para o produto. | |
PRODUCT_PACKAGES | Lista de APKs e módulos para instalar. | Contatos do calendário |
PRODUCT_PACKAGE_OVERLAYS | Indica se serão usados recursos padrão ou se serão adicionadas 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 configuradas por meio de PRODUCT_<PARTITION>_PROPERTIES como em PRODUCT_VENDOR_PROPERTIES para a partição do fornecedor. Nomes de partição suportados: SYSTEM , VENDOR , ODM , SYSTEM_EXT e PRODUCT . |
Configurar o idioma padrão do sistema e o filtro de localidade
Use estas informações para configurar o idioma padrão e o filtro de localidade do sistema e, em seguida, ative 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. Inicialmente, isso é definido como o primeiro código do idioma 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 aos 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 inglesas do inglês e ucraniano - Filtro exclusivo:
^(?!de-IT|es).*
- exclui alemão (variante da Itália) e todas as variantes do espanhol.
- Filtro inclusivo:
Habilite o filtro de localidade
Para ativar o filtro, configure o valor da sequência 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 obtidas 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 alvo. Com esta abordagem, os valores padrão são mantidos 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.
Defina ADB_VENDOR_KEYS para conectar via USB
A variável de ambiente ADB_VENDOR_KEYS
permite que os fabricantes de dispositivos acessem compilações depuráveis (-userdebug e -eng, mas não -user) por meio de 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 desenvolvimento de sistema operacional e especialmente para testes porque 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 lançamento) 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 da árvore de origem. O Google os armazena em
vendor/google/security/adb/
, por exemplo. - Defina a variável de construçã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 sistema operacional.
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 só precisa 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 adb
para tentar essas chaves canônicas primeiro, antes de voltar para a chave do host gerada que requer autorização manual. Quando adb
não consegue se conectar a um dispositivo não autorizado, a mensagem de erro irá sugerir que você defina ADB_VENDOR_KEYS
se ainda não estiver definido.