Konwertowanie z Make na Soong

Przed wydaniem Androida 7.0 system używał wyłącznie GNU Make do opisywania i wykonywania reguł kompilacji. System kompilacji Make jest szeroko obsługiwany i używany, ale w przypadku Androida stał się powolny, podatny na błędy, nierozwijalny i trudny do przetestowania. System kompilacji Song zapewnia elastyczność wymaganą w przypadku kompilacji na Androida.

Dlatego deweloperzy platform powinni jak najszybciej przejść z Make na Song. Aby uzyskać pomoc, prześlij pytania do grupy dyskusyjnej Google android-building.

Co to jest Soong?

System kompilacji Soong został wprowadzony w Androidzie 7.0 (Nougat) jako zamiennik Make. Używa ona narzędzia do klonowania Kati GNU Make i komponentu systemu kompilacji Ninja, aby przyspieszyć kompilację Androida.

Ogólne instrukcjezmiany w systemie kompilacji Androida znajdziesz w opisie Android Make Build System w ramach projektu Android Open Source (AOSP). Aby dowiedzieć się, jak dostosować Make do Soong, zapoznaj się ze zmianami w systemie kompilacji Androida.

Definicje kluczowych terminów znajdziesz w artykule o kompilacji w glosariuszu, a pełne informacje – w plikach referencyjnych Songa.

Porównanie Make i Soong

Oto porównanie konfiguracji Make z Soong, która osiąga ten sam efekt w pliku konfiguracji Soong (pliku Blueprint lub pliku .bp).

Tworzenie przykładu

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libxmlrpc++
LOCAL_MODULE_HOST_OS := linux

LOCAL_RTTI_FLAG := -frtti
LOCAL_CPPFLAGS := -Wall -Werror -fexceptions
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/src

LOCAL_SRC_FILES := $(call \
     all-cpp-files-under,src)
include $(BUILD_SHARED_LIBRARY)

Przykład Soong

cc_library_shared {
     name: "libxmlrpc++",

     rtti: true,
     cppflags: [
           "-Wall",
           "-Werror",
           "-fexceptions",
     ],
     export_include_dirs: ["src"],
     srcs: ["src/**/*.cpp"],

     target: {
           darwin: {
                enabled: false,
           },
     },
}

Przykłady konfiguracji Soong do testów znajdziesz w artykule Prosta konfiguracja kompilacji.

Objaśnienia pól w pliku Android.bp znajdziesz w sekcji Format pliku Android.bp.

Moduły specjalne

Niektóre grupy modułów specjalnych mają unikalne właściwości.

Moduły domyślne

Moduł domyślny umożliwia powtarzanie tych samych właściwości w różnych modułach. Przykład:

cc_defaults {
    name: "gzip_defaults",
    shared_libs: ["libz"],
    stl: "none",
}

cc_binary {
    name: "gzip",
    defaults: ["gzip_defaults"],
    srcs: ["src/test/minigzip.c"],
}

Gotowe moduły

Niektóre wstępnie utworzone typy modułów umożliwiają nadanie modułowi tej samej nazwy co jego odpowiednikom opartym na źródłach. Na przykład cc_prebuilt_binary może mieć nazwę foo, gdy istnieje już cc_binary o tej samej nazwie. Daje to deweloperom elastyczność w wybieraniu wersji, które mają zostać uwzględnione w ostatecznym produkcie. Jeśli konfiguracja kompilacji zawiera obie wersje, wartość parametru prefer w definicji wstępnie skompilowanego modułu określa, która wersja ma mieć priorytet. Pamiętaj, że niektóre gotowe moduły mają nazwy, które nie zaczynają się od prebuilt, na przykład android_app_import.

Moduły przestrzeni nazw

Dopóki Android nie przejdzie całkowicie na Make na Soong, w konfiguracji produktu Make musisz podać wartość PRODUCT_SOONG_NAMESPACES. Jego wartość powinna być rozdzieloną spacjami listą przestrzeni nazw, które Soong eksportuje do Make, aby zostały skompilowane przez polecenie m. Po zakończeniu konwersji Androida na Soong szczegóły włączania przestrzeni nazw mogą się zmienić.

Soong umożliwia modułom w różnych katalogach określanie tej samej nazwy, o ile każdy z nich jest zadeklarowany w osobnej przestrzeni nazw. Nazwa przestrzeni nazw może być zadeklarowana w ten sposób:

soong_namespace {
    imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
}

Pamiętaj, że przestrzeń nazw nie ma właściwości name. Jej nazwą jest automatycznie przypisana ścieżka.

Każdy moduł Soong ma przypisany własny obszar nazw na podstawie swojej lokalizacji w drzewie. Każdy moduł Soong jest uważany za znajdujący się w przestrzeni nazw zdefiniowanej przez soong_namespace znaleziony w pliku Android.bp w bieżącym katalogu lub w najbliższym katalogu nadrzędnym. Jeśli nie zostanie znaleziony żaden moduł soong_namespace, przyjmuje się, że moduł znajduje się w domyślnej ścieżce do korzenia.

Oto przykład: Soong próbuje rozwiązać zależność D zadeklarowaną przez moduł M w przestrzeni nazw N, która importuje przestrzenie nazw I1, I2, I3 itd.

  1. Jeśli D jest pełną nazwą w formie //namespace:module, tylko w określonym zakresie nazw szuka się określonego modułu.
  2. W przeciwnym razie Soong najpierw szuka modułu o nazwie D zadeklarowanego w przestrzeni nazw N.
  3. Jeśli moduł nie istnieje, Soong szuka modułu o nazwie D w przestrzeniach nazw I1, I2, I3 itd.
  4. Na koniec Soong sprawdza katalog główny.