Skorzystaj z informacji zawartych na tej stronie, aby utworzyć pliki make dla swojego urządzenia i produktu.
Każdy nowy moduł Androida musi mieć plik konfiguracyjny, który będzie sterował systemem kompilacji za pomocą metadanych modułu, zależności w czasie kompilacji i instrukcji pakowania. Android korzysta z systemu kompilacji Soong . Aby uzyskać więcej informacji na temat systemu kompilacji systemu Android, zobacz Tworzenie systemu Android.
Zrozumienie warstw kompilacji
Hierarchia kompilacji obejmuje warstwy abstrakcji odpowiadające fizycznemu składowi urządzenia. Warstwy te opisano w poniższej tabeli. Każda warstwa jest powiązana z warstwą znajdującą się nad nią w relacji jeden do wielu. Na przykład architektura może mieć więcej niż jedną płytkę, a każda płytka może zawierać więcej niż jeden produkt. Można zdefiniować element w danej warstwie jako specjalizację elementu w tej samej warstwie, co eliminuje kopiowanie i ułatwia konserwację.
Warstwa | Przykład | Opis |
---|---|---|
Produkt | mójProdukt, mójProdukt_eu, mójProdukt_eu_fr, j2, sdk | Warstwa produktu definiuje specyfikację funkcji produktu wysyłkowego, taką jak moduły do zbudowania, obsługiwane lokalizacje i konfiguracja dla różnych lokalizacji. Innymi słowy, jest to nazwa całego produktu. Zmienne specyficzne dla produktu są zdefiniowane w plikach makefile definicji produktu. Produkt może dziedziczyć z innych definicji produktu, co upraszcza konserwację. Powszechną metodą jest utworzenie produktu podstawowego zawierającego funkcje mające zastosowanie do wszystkich produktów, a następnie utworzenie wariantów produktu w oparciu o ten produkt podstawowy. Na przykład dwa produkty różniące się jedynie radiem (CDMA i GSM) mogą dziedziczyć po tym samym produkcie podstawowym, który nie definiuje radia. |
Płyta/urządzenie | marlin, niebieska linia, koral | Warstwa płytki/urządzenia reprezentuje fizyczną warstwę plastiku na urządzeniu (czyli wzór przemysłowy urządzenia). Warstwa ta reprezentuje również gołe schematy produktu. Należą do nich urządzenia peryferyjne na płycie i ich konfiguracja. Użyte nazwy są jedynie kodami dla różnych konfiguracji płyty/urządzenia. |
Łuk | ramię, x86, ramię64, x86_64 | Warstwa architektury opisuje konfigurację procesora i interfejs binarny aplikacji (ABI) działający na płycie. |
Korzystanie z wariantów kompilacji
Kiedy tworzysz dla konkretnego produktu, przydatne jest posiadanie niewielkich zmian w ostatecznej wersji. W definicji modułu moduł może określić znaczniki z LOCAL_MODULE_TAGS
, które mogą być jedną lub większą liczbą wartości optional
(domyślnych), debug
i eng
.
Jeśli moduł nie określa tagu (przez LOCAL_MODULE_TAGS
), jego tag jest domyślnie optional
. Moduł opcjonalny jest instalowany tylko wtedy, gdy wymaga tego konfiguracja produktu z PRODUCT_PACKAGES
.
Są to obecnie zdefiniowane warianty kompilacji.
Wariant | Opis |
---|---|
eng | To jest domyślny smak.
|
user | Wariant, który miał być ostatecznym wydaniem.
|
userdebug | To samo co user , z tymi wyjątkami:
|
Wytyczne dotyczące debugowania użytkownika
Uruchamianie kompilacji debugowania użytkownika podczas testów pomaga twórcom urządzeń zrozumieć wydajność i możliwości wydań w fazie rozwoju. Aby zachować spójność między kompilacjami użytkownika i debugowania użytkownika oraz aby uzyskać wiarygodne metryki w kompilacjach używanych do debugowania, twórcy urządzeń powinni przestrzegać następujących wskazówek:
- userdebug definiuje się jako kompilację użytkownika z włączonym dostępem roota, z wyjątkiem:
- aplikacje typu userdebug-only, które są uruchamiane wyłącznie na żądanie użytkownika
- Operacje wykonywane tylko podczas bezczynności (na ładowarce/w pełni naładowany), takie jak używanie
dex2oatd
w porównaniu zdex2oat
do kompilacji w tle
- Nie uwzględniaj funkcji, które są domyślnie włączone/wyłączone w zależności od typu kompilacji. Odradza się programistom korzystanie z jakichkolwiek form rejestrowania wpływających na żywotność baterii, takich jak rejestrowanie debugowania lub zrzucanie sterty.
- Wszelkie funkcje debugowania, które są domyślnie włączone w userdebug, powinny być jasno zdefiniowane i udostępnione wszystkim programistom pracującym nad projektem. Funkcje debugowania należy włączać tylko na ograniczony czas, do czasu rozwiązania problemu, który próbujesz debugować.
Dostosowywanie kompilacji za pomocą nakładek zasobów
System kompilacji Androida wykorzystuje nakładki zasobów, aby dostosować produkt na etapie kompilacji. Nakładki zasobów określają pliki zasobów, które są stosowane zamiast ustawień domyślnych. Aby użyć nakładek zasobów, zmodyfikuj plik kompilacji projektu, aby ustawić PRODUCT_PACKAGE_OVERLAYS
na ścieżkę względem katalogu najwyższego poziomu. Ścieżka ta staje się cieniem katalogu głównego przeszukiwanym wraz z bieżącym katalogiem głównym, gdy system kompilacji szuka zasobów.
Najczęściej dostosowywane ustawienia znajdują się w pliku frameworks/base/core/res/res/values/config.xml .
Aby skonfigurować nakładkę zasobów na tym pliku, dodaj katalog nakładki do pliku kompilacji projektu, korzystając z jednej z poniższych opcji:
PRODUCT_PACKAGE_OVERLAYS := device/device-implementer/device-name/overlay
Lub
PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay
Następnie dodaj plik nakładki do katalogu, na przykład:
vendor/foobar/overlay/frameworks/base/core/res/res/values/config.xml
Wszelkie ciągi lub tablice ciągów znalezione w pliku config.xml
nakładki zastępują te znalezione w oryginalnym pliku.
Budowanie produktu
Pliki źródłowe urządzenia możesz porządkować na wiele różnych sposobów. Oto krótki opis jednego ze sposobów organizacji implementacji Pixela.
Pixel jest zaimplementowany z główną konfiguracją urządzenia o nazwie marlin
. Na podstawie tej konfiguracji urządzenia tworzony jest produkt z plikiem make z definicją produktu, który deklaruje informacje o urządzeniu specyficzne dla produktu, takie jak nazwa i model. Możesz wyświetlić katalog device/google/marlin
aby zobaczyć, jak to wszystko jest skonfigurowane.
Pisanie plików makefile produktów
Poniższe kroki opisują sposób konfigurowania plików makefile produktów w sposób podobny do linii produktów Pixel:
- Utwórz katalog
device/ <company-name> / <device-name>
dla swojego produktu. Na przykładdevice/google/marlin
. Ten katalog będzie zawierał kod źródłowy Twojego urządzenia wraz z plikami make do ich zbudowania. - Utwórz plik makefile
device.mk
, który deklaruje pliki i moduły potrzebne dla urządzenia. Na przykład zobaczdevice/google/marlin/device-marlin.mk
. - Utwórz plik makefile definicji produktu, aby utworzyć konkretny produkt na podstawie urządzenia. Następujący plik makefile został pobrany jako przykład z
device/google/marlin/aosp_marlin.mk
. Zwróć uwagę, że produkt dziedziczy z plikówdevice/google/marlin/device-marlin.mk
ivendor/google/marlin/device-vendor-marlin.mk
poprzez plik makefile, deklarując jednocześnie informacje specyficzne dla produktu, takie jak nazwa, marka, i modelka.# 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
Zobacz Ustawianie zmiennych definicji produktu , aby zapoznać się z dodatkowymi zmiennymi specyficznymi dla produktu, które możesz dodać do plików makefile.
- Utwórz plik
AndroidProducts.mk
wskazujący pliki makefile produktu. W tym przykładzie potrzebny jest tylko plik makefile definicji produktu. Poniższy przykład pochodzi zdevice/google/marlin/AndroidProducts.mk
(który zawiera zarówno Marlin, Pixel, jak i Sailfish, Pixel XL, które mają najwięcej wspólnych konfiguracji):PRODUCT_MAKEFILES := \ $(LOCAL_DIR)/aosp_marlin.mk \ $(LOCAL_DIR)/aosp_sailfish.mk COMMON_LUNCH_CHOICES := \ aosp_marlin-userdebug \ aosp_sailfish-userdebug
- Utwórz plik makefile
BoardConfig.mk
zawierający konfiguracje specyficzne dla płyty. Na przykład zobaczdevice/google/marlin/BoardConfig.mk
. - Tylko w przypadku Androida 9 i starszych wersji utwórz plik
vendorsetup.sh
, aby dodać swój produkt („zestaw lunchowy”) do kompilacji wraz z wariantem kompilacji oddzielonym myślnikiem. Na przykład:add_lunch_combo <product-name>-userdebug
- W tym momencie możesz stworzyć więcej wariantów produktu w oparciu o to samo urządzenie.
Ustawianie zmiennych definicji produktu
Zmienne specyficzne dla produktu są zdefiniowane w pliku makefile produktu. W tabeli przedstawiono niektóre zmienne przechowywane w pliku definicji produktu.
Zmienny | Opis | Przykład |
---|---|---|
PRODUCT_AAPT_CONFIG | aapt konfiguracje do użycia podczas tworzenia pakietów. | |
PRODUCT_BRAND | Marka (np. przewoźnik), dla której dostosowane jest oprogramowanie. | |
PRODUCT_CHARACTERISTICS | aapt , aby umożliwić dodanie zasobów specyficznych dla wariantu do pakietu. | tablet , nosdcard |
PRODUCT_COPY_FILES | Lista słów takich jak source_path:destination_path . Podczas tworzenia tego produktu plik w ścieżce źródłowej powinien zostać skopiowany do ścieżki docelowej. Reguły dotyczące kroków kopiowania są zdefiniowane w config/makefile . | |
PRODUCT_DEVICE | Nazwa wzoru przemysłowego. Jest to również nazwa płytki i system kompilacji używa jej do zlokalizowania BoardConfig.mk . | tuna |
PRODUCT_LOCALES | Oddzielona spacjami lista dwuliterowych kodów języka i par dwuliterowych kodów krajów opisujących kilka ustawień użytkownika, takich jak język interfejsu użytkownika oraz formatowanie godziny, daty i waluty. Pierwsze ustawienie regionalne wymienione w PRODUCT_LOCALES jest używane jako domyślne ustawienie regionalne produktu. | en_GB , de_DE , es_ES , fr_CA |
PRODUCT_MANUFACTURER | Nazwa producenta. | acme |
PRODUCT_MODEL | Widoczna dla użytkownika końcowego nazwa produktu końcowego. | |
PRODUCT_NAME | Widoczna dla użytkownika końcowego nazwa całego produktu. Pojawia się na ekranie Ustawienia > Informacje . | |
PRODUCT_OTA_PUBLIC_KEYS | Lista kluczy publicznych OTA dla produktu. | |
PRODUCT_PACKAGES | Lista plików APK i modułów do zainstalowania. | Kontakty kalendarza |
PRODUCT_PACKAGE_OVERLAYS | Wskazuje, czy użyć zasobów domyślnych, czy dodać nakładki specyficzne dla produktu. | vendor/acme/overlay |
PRODUCT_SYSTEM_PROPERTIES | Lista przypisań właściwości systemu w formacie "key=value" dla partycji systemowej. Właściwości systemu dla innych partycji można ustawić poprzez PRODUCT_<PARTITION>_PROPERTIES tak jak w PRODUCT_VENDOR_PROPERTIES dla partycji dostawcy. Obsługiwane nazwy partycji: SYSTEM , VENDOR , ODM , SYSTEM_EXT i PRODUCT . |
Konfigurowanie domyślnego języka systemu i filtra ustawień regionalnych
Skorzystaj z tych informacji, aby skonfigurować domyślny język i systemowy filtr ustawień regionalnych, a następnie włącz filtr ustawień regionalnych dla nowego typu urządzenia.
Nieruchomości
Skonfiguruj zarówno domyślny język, jak i filtr ustawień regionalnych systemu, korzystając z dedykowanych właściwości systemu:
-
ro.product.locale
: do ustawiania domyślnych ustawień regionalnych. Początkowo jest to ustawione na pierwsze ustawienia regionalne w zmiennejPRODUCT_LOCALES
; możesz zastąpić tę wartość. (Aby uzyskać więcej informacji, zobacz tabelę Ustawianie zmiennych definicji produktu .) -
ro.localization.locale_filter
: do ustawiania filtru ustawień regionalnych przy użyciu wyrażenia regularnego stosowanego do nazw ustawień regionalnych. Na przykład:- Filtr włączający:
^(de-AT|de-DE|en|uk).*
- dopuszcza tylko język niemiecki (warianty austriackie i niemieckie), wszystkie angielskie warianty języka angielskiego i ukraińskiego - Ekskluzywny filtr:
^(?!de-IT|es).*
- wyklucza język niemiecki (wariant włoski) i wszystkie warianty języka hiszpańskiego.
- Filtr włączający:
Włączanie filtru regionalnego
Aby włączyć filtr, ustaw wartość ciągu właściwości systemowej ro.localization.locale_filter
.
Ustawiając wartość właściwości filtra i domyślny język w oem/oem.prop
podczas kalibracji fabrycznej, możesz skonfigurować ograniczenia bez wypalania filtra w obrazie systemu. Upewnij się, że te właściwości zostaną pobrane z partycji OEM, dodając je do zmiennej PRODUCT_OEM_PROPERTIES
, jak wskazano poniżej:
# Delegation for OEM customization PRODUCT_OEM_PROPERTIES += \ ro.product.locale \ ro.localization.locale_filter
Następnie podczas produkcji rzeczywiste wartości są zapisywane w oem/oem.prop
, aby odzwierciedlić wymagania docelowe. Dzięki takiemu podejściu wartości domyślne są zachowywane podczas przywracania ustawień fabrycznych, więc ustawienia początkowe wyglądają dla użytkownika dokładnie tak samo, jak pierwsza konfiguracja.
Ustawianie ADB_VENDOR_KEYS do połączenia przez USB
Zmienna środowiskowa ADB_VENDOR_KEYS
umożliwia producentom urządzeń dostęp do debugowalnych kompilacji (-userdebug i -eng, ale nie -user) za pośrednictwem adb bez ręcznej autoryzacji. Zwykle adb generuje unikalny klucz uwierzytelniający RSA dla każdego komputera klienckiego, który wysyła do dowolnego podłączonego urządzenia. To jest klucz RSA pokazany w oknie dialogowym autoryzacji adb. Alternatywnie możesz wbudować znane klucze w obraz systemu i udostępnić je klientowi adb. Jest to przydatne przy opracowywaniu systemu operacyjnego, a zwłaszcza podczas testowania, ponieważ pozwala uniknąć konieczności ręcznej interakcji z oknem dialogowym autoryzacji adb.
Aby utworzyć klucze dostawcy, jedna osoba (zwykle menedżer ds. wersji) powinna:
- Wygeneruj parę kluczy za pomocą
adb keygen
. W przypadku urządzeń Google Google generuje nową parę kluczy dla każdej nowej wersji systemu operacyjnego. - Sprawdź pary kluczy gdzieś w drzewie źródłowym. Google przechowuje je na przykład w
vendor/google/security/adb/
. - Ustaw zmienną kompilacji
PRODUCT_ADB_KEYS
tak, aby wskazywała katalog kluczy. Google robi to, dodając plikAndroid.mk
do katalogu kluczy o treściPRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub
, co pomaga pamiętać o wygenerowaniu nowej pary kluczy dla każdej wersji systemu operacyjnego.
Oto plik makefile, którego Google używa w katalogu, w którym przechowujemy nasze sprawdzone pary kluczy dla każdej wersji:
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
Aby użyć tych kluczy dostawcy, inżynier musi jedynie ustawić zmienną środowiskową ADB_VENDOR_KEYS
tak, aby wskazywała katalog, w którym przechowywane są pary kluczy. To mówi adb
, aby najpierw wypróbował te klucze kanoniczne, zanim wróci do wygenerowanego klucza hosta, który wymaga ręcznej autoryzacji. Gdy adb
nie może połączyć się z nieautoryzowanym urządzeniem, komunikat o błędzie zasugeruje ustawienie ADB_VENDOR_KEYS
, jeśli nie jest jeszcze ustawione.