Use as informações apresentadas nesta página para criar os makefiles para seu dispositivo e produto.
Cada novo módulo do Android precisa ter um arquivo de configuração para direcionar o sistema de build com metadados do módulo, dependências de tempo de compilação e instruções de empacotamento. O Android usa o sistema de build Soong (link em inglês). Consulte Criar para o Android para mais informações sobre o sistema de build do Android.
Compreender as camadas de build
A hierarquia de build 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 |
---|---|---|
Produto | myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk | A camada de produto define a especificação de recursos de um produto de venda, como os módulos a serem criados, as localidades aceitas e a configuração de várias localidades. Em outras palavras, esse é o nome do produto geral. Variáveis específicas de produto são definidas nos makefiles de definição do produto. Um produto pode ter heranças de outras definições de produtos, o que simplifica a manutenção. Um método comum é criar um produto base contendo recursos aplicáveis a todos os produtos e, em seguida, criar variantes do produto com base nele. Por exemplo, dois produtos que diferem apenas nos rádios (CDMA versus GSM) podem herdar do mesmo produto base que não define um rádio. |
Placa/dispositivo | marlin, blueline, coral | A camada de placa/dispositivo representa a camada física de plástico no dispositivo (ou seja, o design industrial do dispositivo). Essa camada também representa o esquema cru de um produto. Isso inclui os periféricos na placa e sua configuração. Os nomes usados são meramente códigos para diferentes configurações de placa/dispositivo. |
Arch | arm, x86, arm64, x86_64 | A camada de arquitetura descreve a configuração do processador e a Interface binária de aplicativo (ABI) em execução na placa. |
Usar variantes de build
Ao criar um produto específico, é conveniente ter pequenas
variantes no build de lançamento. Em uma definição, 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
), a tag será optional
por padrão. Um módulo opcional será instalado somente se for exigido pela configuração do produto com PRODUCT_PACKAGES
.
Estas são as variantes de build definidas atualmente:
Variante | Descrição |
---|---|
eng
|
Esta é a variação padrão.
|
user
|
A variante escolhida para ser a versão final.
|
userdebug
|
O mesmo que user , com estas exceções:
|
Diretrizes de userdebug
A execução de builds userdebug nos testes ajuda os desenvolvedores de dispositivos a entenderem o desempenho e a potência das versões em desenvolvimento. Para manter a consistência entre os builds de usuário e de userdebug e para receber métricas confiáveis em builds usados para depuração, os desenvolvedores de dispositivos devem seguir estas diretrizes:
- userdebug deve ser definido como um build de usuário com acesso raiz ativado, exceto:
- Apps somente para userdebug que são executados apenas sob demanda pelo usuário.
- Operações que são executadas apenas durante a manutenção ociosa (no carregador/totalmente carregado), por exemplo, o uso de
dex2oatd
versusdex2oat
para compilações em segundo plano.
- Não deve haver recursos que dependam do tipo de build para serem ativados por padrão ou não. Não é recomendável que os desenvolvedores usem qualquer forma de registro que afete a vida útil da bateria, como o log de depuração ou o despejo de heap.
- Quaisquer recursos de depuração ativados por padrão no userdebug precisam ser claramente definidos e compartilhados com todos os desenvolvedores que trabalham no projeto. Recomendamos ativar recursos de depuração somente por tempo limitado, até que o problema que você está tentando depurar seja resolvido.
Personalizar o build com sobreposições de recursos
O sistema de build do Android usa sobreposições de recursos para personalizar
um produto durante o build. As sobreposições de recursos especificam arquivos de recursos aplicados sobre os padrões. Para usar sobreposições de recursos, modifique o arquivo de build do projeto
para definir o PRODUCT_PACKAGE_OVERLAYS
como um
caminho relativo para seu diretório de nível superior. Esse caminho se torna uma raiz paralela pesquisada junto à
raiz atual quando o sistema de build procura recursos.
As configurações mais personalizadas com mais frequência estão contidas no arquivo frameworks/base/core/res/res/values/config.xml.
Para configurar uma sobreposição de recurso nesse arquivo, adicione o diretório da sobreposição ao arquivo de build do projeto usando:
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
Todas as strings ou matrizes de string encontradas no arquivo de sobreposição config.xml
substituem as encontradas no arquivo original.
Criar um produto
É possível organizar os arquivos de origem do dispositivo de maneiras diferentes. Veja uma breve descrição de uma maneira de organizar uma implementação do Pixel.
O Pixel é implementado com uma configuração de dispositivo principal chamada marlin
. Com base nessa 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, por exemplo, o nome e o modelo. Consulte o diretório device/google/marlin
para saber como tudo isso está configurado.
Criar makefiles de produto
As etapas abaixo descrevem como configurar makefiles de produtos de maneira semelhante à linha de produtos do Pixel:
- Crie um diretório
device/<company-name>/<device-name>
para o produto. Por exemplo,device/google/marlin
. Esse diretório conterá o código-fonte do seu dispositivo e os makefiles para criá-los. - Crie um makefile
device.mk
que declare os arquivos e módulos necessários para o dispositivo. Veja um exemplo em:device/google/marlin/device-marlin.mk
. - Crie um makefile de definição de produto para criar um produto específico com base no dispositivo. O makefile a seguir foi retirado de
device/google/marlin/aosp_marlin.mk
como exemplo. Observe que o produto é herdado dos arquivosdevice/google/marlin/device-marlin.mk
evendor/google/marlin/device-vendor-marlin.mk
pelo makefile, além de declarar 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 Como definir variáveis de definição de produto para ver outras variáveis específicas do produto que podem ser adicionadas 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 o Pixel (marlin) e o Pixel XL (sailfish) que compartilharam 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
contendo as configurações específicas da placa. Veja um exemplo em:device/google/marlin/BoardConfig.mk
. - Apenas para o Android 9 e versões anteriores, crie um arquivo
vendorsetup.sh
para adicionar seu produto (um "lunch combo") ao build com uma variante de build separada por um traço. Exemplo:add_lunch_combo <product-name>-userdebug
- Nesse ponto, você pode criar mais variantes de produtos com base no mesmo dispositivo.
Estabelecer variáveis de definição de produto
Variáveis específicas de 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 de aapt a serem usadas ao criar pacotes.
|
|
PRODUCT_BRAND
|
A marca (por exemplo, operadora) para a qual o software é personalizado. | |
PRODUCT_CHARACTERISTICS
|
Características do aapt para permitir a inclusão de recursos específicos da variante em um pacote.
|
tablet , nosdcard
|
PRODUCT_COPY_FILES
|
Lista de palavras como source_path:destination_path . O arquivo no caminho de origem precisa ser copiado para o caminho de destino ao criar esse produto. As regras para as etapas de cópia são definidas em config/makefile .
|
|
PRODUCT_DEVICE
|
Nome do design industrial. Esse também é o nome da placa, e o sistema de build o utiliza para localizar o BoardConfig.mk .
|
tuna
|
PRODUCT_LOCALES
|
Uma lista separada por espaço 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, por exemplo, o idioma da interface e a formatação de data, hora e moeda. A primeira localidade listada em PRODUCT_LOCALES é usada como a 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 dos APKs e módulos a serem instalados. | Contatos do calendário |
PRODUCT_PACKAGE_OVERLAYS
|
Indica se os recursos padrão precisam ser usados ou se alguma sobreposição específica do produto precisa ser adicionada. |
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 com
suporte: SYSTEM , VENDOR , ODM ,
SYSTEM_EXT e PRODUCT .
|
Configurar o filtro de localidade e o idioma padrão do sistema
Use essas informações para configurar o filtro de localidade e o idioma padrão 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, essa propriedade é definida como a primeira localidade na variávelPRODUCT_LOCALES
e é possível substituir esse valor. Para mais informações, consulte a tabela Definir 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 incluso:
^(de-AT|de-DE|en|uk).*
: permite apenas o alemão (variantes da Áustria e da Alemanha), todas as variantes inglesas do inglês e ucraniano. - Filtro exclusivo,
^(?!de-IT|es).*
: exclui o alemão (variante da Itália) e todas as variantes do espanhol.
- Filtro incluso:
Ativar o filtro de localidade
Para ativar o filtro, defina o valor da string da propriedade do sistema ro.localization.locale_filter
.
Ao definir o valor da propriedade de filtro e o idioma padrão com oem/oem.prop
durante
a calibração de fábrica, você pode configurar restrições sem colocar o filtro na imagem do sistema.
Confira se as propriedades foram selecionadas da partição do OEM ao as adicionar à
variável PRODUCT_OEM_PROPERTIES
, conforme indicado abaixo:
# Delegation for OEM customization
PRODUCT_OEM_PROPERTIES += \
ro.product.locale \
ro.localization.locale_filter
Em seguida, os valores reais são gravados na oem/oem.prop
para refletir os requisitos de destino
na produção. Nessa abordagem, os valores padrão são mantidos durante a redefinição de fábrica. As
configurações iniciais se parecem exatamente com a primeira configuração do usuário.
Definir ADB_VENDOR_KEYS para conexão por USB
A variável de ambiente ADB_VENDOR_KEYS
permite que os fabricantes de dispositivos acessem
os builds depuráveis (-userdebug e -eng, mas não -user) por adb sem autorização manual.
Normalmente, o adb gera para cada computador cliente uma chave de autenticação RSA exclusiva que será enviada
para qualquer dispositivo conectado. Essa é a mesma 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 no desenvolvimento do SO, especialmente em testes, porque evita a necessidade de interação
manual com a caixa de diálogo de autorização do adb.
Para criar chaves de fornecedores, uma pessoa (geralmente um gerente de versão) precisa fazer o seguinte:
- Gerar um par de chaves usando
adb keygen
. Para dispositivos do Google, um novo par de chaves é gerado para cada nova versão do SO. - Fazer check-in de pares de chaves, em algum lugar na árvore de origem. O Google as armazena em
vendor/google/security/adb/
, por exemplo. - Definir as
PRODUCT_ADB_KEYS
da variável de build para apontar para o diretório de chaves. Para fazer isso, o Google adiciona um arquivoAndroid.mk
no diretório de chaves que dizPRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub
, ajudando a garantir a geração de um novo par de chaves para cada versão do SO.
Veja o makefile que o Google usa no diretório em que 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
de modo que aponte para o diretório em que os pares de chaves são armazenados.
Isso instrui o adb
a testar essas chaves canônicas antes de recorrer à chave de
host gerada que requer autorização manual. Quando adb
não conseguir 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.