Skorzystaj z informacji na tej stronie, aby utworzyć pliki makefile dla urządzenia i produktu.
Każdy nowy moduł Androida musi mieć plik konfiguracyjny, który zawiera metadane modułu, zależności czasu kompilacji i instrukcje pakowania. Android korzysta z systemu kompilacji Soong. Więcej informacji o systemie kompilacji Androida znajdziesz w artykule Kompilowanie Androida.
Informacje o warstwach kompilacji
Hierarchia kompilacji obejmuje warstwy abstrakcji odpowiadające fizycznej budowie urządzenia. Warstwy te opisujemy w tabeli poniżej. Każda warstwa jest powiązana z warstwą powyżej relacją jeden do wielu. Na przykład architektura może mieć więcej niż jedną tablicę, a każda tablica może zawierać więcej niż 1 produkt. Możesz zdefiniować element w danej warstwie jako specjalizację elementu w tej samej warstwie, co eliminuje kopiowanie i upraszcza konserwację.
Warstwa | Przykład | Opis |
---|---|---|
Produkt | myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk | Warstwa produktu określa specyfikację funkcji usługi dostawy, np. moduły do utworzenia, obsługiwane regiony i konfigurację dla różnych regionów. Innymi słowy, jest to nazwa produktu jako całości. Zmienne specyficzne dla produktu są zdefiniowane w plikach makefile definicji produktu. Produkt może dziedziczyć definicje innych produktów, co upraszcza zarządzanie. Często stosowaną metodą jest utworzenie produktu podstawowego, który zawiera funkcje mające zastosowanie do wszystkich produktów, a następnie utworzenie wariantów produktu na podstawie tego produktu podstawowego. Na przykład 2 produkty, które różnią się tylko radiem (CDMA i GSM), mogą dziedziczyć po tym samym produkcie bazowym, który nie definiuje radia. |
Płyta/urządzenie | marlin, blueline, coral | Warstwa płyty/urządzenia reprezentuje fizyczną warstwę plastiku na urządzeniu (czyli jego konstrukcję). Ta warstwa przedstawia też schematy produktu. Obejmują one urządzenia peryferyjne na płycie i ich konfigurację. Używane nazwy to tylko kody różnych konfiguracji płyty lub urządzenia. |
Łuk | arm, x86, arm64, x86_64 | Warstwa architektury opisuje konfigurację procesora i interfejs binarny aplikacji (ABI) działający na płycie. |
Korzystanie z wariantów kompilacji
Podczas tworzenia wersji na konkretny produkt przydatne są drobne
różnice w ostatecznej wersji. W definicji modułu można określić tagi za pomocą parametru LOCAL_MODULE_TAGS
, który może zawierać co najmniej 1 wartość z tych: optional
(domyślna), debug
i eng
.
Jeśli moduł nie określa tagu (za pomocą LOCAL_MODULE_TAGS
), jego tag domyślnie przyjmuje wartość optional
. Opcjonalny moduł jest instalowany tylko wtedy, gdy jest wymagany przez konfigurację produktu z PRODUCT_PACKAGES
.
Są to obecnie zdefiniowane warianty kompilacji.
Wariant | Opis |
---|---|
eng
|
Jest to domyślny wariant.
|
user
|
Wariant, który ma być ostateczną wersją.
|
userdebug
|
Taka sama cena jak w hotelu user , z tymi wyjątkami:
|
Wskazówki dotyczące wersji userdebug
Uruchamianie wersji userdebug w testach pomaga deweloperom urządzeń poznać wydajność i zużycie energii w przypadku wersji w trakcie opracowywania. Aby zachować spójność między wersjami użytkownika i wersjami debugowania użytkownika oraz uzyskać wiarygodne dane w wersjach używanych do debugowania, deweloperzy urządzeń powinni postępować zgodnie z tymi wytycznymi:
- userdebug to kompilacja użytkownika z włączonym dostępem do roota, z wyjątkiem:
- aplikacje tylko do debugowania przez użytkownika, które są uruchamiane tylko na żądanie użytkownika;
- Operacje, które są wykonywane tylko podczas konserwacji w trybie bezczynności (podczas ładowania lub po pełnym naładowaniu), np. używanie
dex2oatd
zamiastdex2oat
do kompilacji w tle.
- Nie uwzględniaj funkcji, które są domyślnie włączone lub wyłączone w zależności od typu kompilacji. Deweloperzy nie powinni używać żadnej formy rejestrowania, która wpływa na żywotność baterii, np. rejestrowania debugowania lub zrzutu sterty.
- Wszystkie funkcje debugowania, które są domyślnie włączone w wersji userdebug, powinny być jasno określone i udostępnione wszystkim deweloperom pracującym nad projektem. Funkcje debugowania należy włączać tylko na ograniczony czas, dopóki nie zostanie rozwiązany problem, który próbujesz debugować.
Dostosowywanie kompilacji za pomocą nakładek na zasoby
System kompilacji Androida używa nakładek zasobów do dostosowywania produktu w momencie kompilacji. Nakładki zasobów określają pliki zasobów, które są stosowane na domyślne. Aby używać nakładek zasobów, zmodyfikuj plik kompilacji projektu, aby ustawić PRODUCT_PACKAGE_OVERLAYS
na ścieżkę względną względem katalogu najwyższego poziomu. Ta ścieżka staje się katalogiem głównym cienia, który jest przeszukiwany 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ę zasobu w tym pliku, dodaj katalog nakładki do pliku kompilacji projektu, korzystając z jednej z tych metod:
PRODUCT_PACKAGE_OVERLAYS := device/device-implementer/device-name/overlay
lub
PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay
Następnie dodaj do katalogu plik nakładki, np.:
vendor/foobar/overlay/frameworks/base/core/res/res/values/config.xml
Wszelkie ciągi znaków lub tablice ciągów znaków znalezione w pliku nakładki config.xml
zastępują te znalezione w pliku oryginalnym.
Tworzenie produktu
Pliki źródłowe na urządzeniu możesz porządkować na różne sposoby. Oto krótki opis jednego ze sposobów organizacji wdrożenia Pixela.
Pixel jest wdrażany z konfiguracją urządzenia głównego o nazwie marlin
. Na podstawie tej konfiguracji urządzenia tworzony jest produkt z plikiem makefile definicji produktu, który zawiera informacje o urządzeniu, takie jak nazwa i model. Możesz wyświetlić device/google/marlin
katalog, aby zobaczyć, jak to wszystko jest skonfigurowane.
Tworzenie plików makefile produktów
Poniżej znajdziesz opis konfigurowania plików makefile produktów w sposób podobny do tego, w jaki konfigurowane są pliki makefile linii produktów Pixel:
- Utwórz katalog
device/<company-name>/<device-name>
dla swojego produktu. Na przykład:device/google/marlin
. Ten katalog będzie zawierać kod źródłowy urządzenia wraz z plikami makefile do jego skompilowania. - Utwórz plik
device.mk
, który deklaruje pliki i moduły potrzebne na urządzeniu. Przykład znajdziesz w sekcjidevice/google/marlin/device-marlin.mk
. - Utwórz plik makefile definicji produktu, aby utworzyć konkretny produkt na podstawie urządzenia. Poniższy plik makefile pochodzi 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
za pomocą pliku makefile, a także deklaruje informacje specyficzne dla produktu, takie jak nazwa, marka i model.# 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
Więcej informacji o dodatkowych zmiennych specyficznych dla produktów, które możesz dodać do plików makefile, znajdziesz w artykule Ustawianie zmiennych definicji produktu.
- Utwórz plik
AndroidProducts.mk
, który wskazuje pliki makefile produktu. W tym przykładzie potrzebny jest tylko plik makefile definicji produktu. Poniższy przykład pochodzi zdevice/google/marlin/AndroidProducts.mk
(zawiera zarówno marlina, czyli Pixela, jak i żaglówkę, czyli Pixela XL, które miały podobną konfigurację):PRODUCT_MAKEFILES := \ $(LOCAL_DIR)/aosp_marlin.mk \ $(LOCAL_DIR)/aosp_sailfish.mk COMMON_LUNCH_CHOICES := \ aosp_marlin-userdebug \ aosp_sailfish-userdebug
- Utwórz plik
BoardConfig.mk
makefile zawierający konfiguracje specyficzne dla płyty. Przykład znajdziesz w sekcjidevice/google/marlin/BoardConfig.mk
. - W przypadku Androida 9 i starszych wersji utwórz plik
vendorsetup.sh
, aby dodać produkt („zestaw lunchowy”) do kompilacji wraz z wariantem kompilacji oddzielonymi myślnikiem. Na przykład:add_lunch_combo <product-name>-userdebug
- Na tym etapie możesz utworzyć więcej wariantów produktu na podstawie tego samego urządzenia.
Ustawianie zmiennych definicji produktu
Zmienne specyficzne dla produktu są zdefiniowane w pliku makefile produktu. Tabela zawiera niektóre zmienne przechowywane w pliku definicji produktu.
Zmienna | Opis | Przykład |
---|---|---|
PRODUCT_AAPT_CONFIG
|
aapt konfiguracji do użycia podczas tworzenia pakietów.
|
|
PRODUCT_BRAND
|
Marka (np. operator), dla której oprogramowanie jest dostosowane. | |
PRODUCT_CHARACTERISTICS
|
aapt charakterystyki, aby umożliwić dodawanie do pakietu zasobów specyficznych dla wariantu.
|
tablet , nosdcard
|
PRODUCT_COPY_FILES
|
Lista słów podobnych do source_path:destination_path . Podczas tworzenia tego produktu plik znajdujący się 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łyty, która jest używana przez system kompilacji do lokalizowania BoardConfig.mk .
|
tuna
|
PRODUCT_LOCALES
|
Lista par dwuliterowych kodów języka i dwuliterowych kodów kraju oddzielonych spacjami, które opisują kilka ustawień użytkownika, np. język interfejsu oraz formatowanie czasu, 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
|
Nazwa produktu końcowego widoczna dla użytkownika. | |
PRODUCT_NAME
|
Nazwa produktu widoczna dla użytkownika. Wyświetla się na ekranie Ustawienia > Informacje. | |
PRODUCT_OTA_PUBLIC_KEYS
|
Lista kluczy publicznych OTA (Over-the-Air) dla produktu. | |
PRODUCT_PACKAGES
|
Lista plików APK i modułów do zainstalowania. | Kontakty w Kalendarzu |
PRODUCT_PACKAGE_OVERLAYS
|
Określa, czy używać zasobów domyślnych, czy dodawać nakładki specyficzne dla produktu. |
vendor/acme/overlay
|
PRODUCT_SYSTEM_PROPERTIES
|
Lista przypisań właściwości systemowych w formacie "key=value" dla partycji systemowej. Właściwości systemowe dla innych partycji można ustawić za pomocą PRODUCT_<PARTITION>_PROPERTIES , tak jak w przypadku partycji dostawcy – PRODUCT_VENDOR_PROPERTIES . Obsługiwane nazwy partycji: SYSTEM , VENDOR , ODM , SYSTEM_EXT i PRODUCT .
|
Konfigurowanie domyślnego języka systemu i filtra regionalnego
Użyj tych informacji, aby skonfigurować domyślny filtr języka i ustawień regionalnych systemu, a następnie włączyć filtr ustawień regionalnych dla nowego typu urządzenia.
Właściwości
Skonfiguruj zarówno domyślny język, jak i filtr ustawień regionalnych systemu za pomocą specjalnych właściwości systemowych:
ro.product.locale
: do ustawiania domyślnego regionu. Początkowo jest ona ustawiona na pierwszy język w zmiennejPRODUCT_LOCALES
. Możesz zastąpić tę wartość. (Więcej informacji znajdziesz w tabeli Ustawianie zmiennych definicji produktu).ro.localization.locale_filter
: do ustawiania filtra języka za pomocą wyrażenia regularnego stosowanego do nazw języków. Na przykład:- Filtr uwzględniający:
^(de-AT|de-DE|en|uk).*
– zezwala tylko na język niemiecki (warianty austriacki i niemiecki), wszystkie warianty języka angielskiego i język ukraiński. - Filtr wykluczający:
^(?!de-IT|es).*
– wyklucza język niemiecki (wariant włoski) i wszystkie warianty języka hiszpańskiego.
- Filtr uwzględniający:
Włącz filtr języka
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 język domyślny za pomocą oem/oem.prop
podczas kalibracji fabrycznej, możesz skonfigurować ograniczenia bez wbudowywania filtra w obraz systemu.
Aby mieć pewność, że te właściwości są pobierane z partycji OEM, dodaj je do zmiennej PRODUCT_OEM_PROPERTIES
w sposób podany poniżej:
# Delegation for OEM customization
PRODUCT_OEM_PROPERTIES += \
ro.product.locale \
ro.localization.locale_filter
Następnie w środowisku produkcyjnym rzeczywiste wartości są zapisywane w oem/oem.prop
, aby odzwierciedlać wymagania docelowe. Dzięki temu podczas przywracania ustawień fabrycznych zachowywane są wartości domyślne, więc początkowe ustawienia wyglądają dla użytkownika dokładnie tak samo jak podczas pierwszej konfiguracji.
Ustawienie zmiennej ADB_VENDOR_KEYS w celu połączenia przez USB
Zmienna środowiskowa ADB_VENDOR_KEYS
umożliwia producentom urządzeń uzyskiwanie dostępu do wersji debugowania (–userdebug i –eng, ale nie –user) przez adb bez ręcznej autoryzacji.
Zwykle adb generuje niepowtarzalny klucz uwierzytelniania RSA dla każdego komputera klienckiego, który wysyła do każdego podłączonego urządzenia. Jest to klucz RSA widoczny w oknie dialogowym autoryzacji adb. Alternatywnie możesz wbudować znane klucze w obraz systemu i udostępnić je klientowi adb.
Jest to przydatne w przypadku tworzenia systemów operacyjnych, a zwłaszcza testowania, ponieważ nie trzeba ręcznie wchodzić w interakcję z oknem autoryzacji adb.
Aby utworzyć klucze dostawcy, jedna osoba (zwykle menedżer wersji) powinna:
- Wygeneruj parę kluczy za pomocą
adb keygen
. W przypadku urządzeń Google generuje nową parę kluczy dla każdej nowej wersji systemu operacyjnego. - Sprawdź pary kluczy 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 do katalogu kluczy plikAndroid.mk
, który zawiera tekstPRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub
. Dzięki temu pamiętamy, aby generować nową parę kluczy dla każdej wersji systemu operacyjnego.
Oto plik makefile, którego Google używa w katalogu, w którym przechowujemy 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 tylko ustawić zmienną środowiskową ADB_VENDOR_KEYS
, aby wskazywała katalog, w którym są przechowywane pary kluczy.
Dzięki temu adb
najpierw spróbuje użyć tych kluczy kanonicznych, a potem wygenerowanego klucza hosta, który wymaga ręcznej autoryzacji. Gdy adb
nie może połączyć się z nieautoryzowanym urządzeniem, w komunikacie o błędzie pojawi się sugestia, aby ustawić ADB_VENDOR_KEYS
, jeśli nie jest jeszcze ustawiony.