Google is committed to advancing racial equity for Black communities. See how.
Ta strona została przetłumaczona przez Cloud Translation API.
Switch to English

Soong Build System

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

Z tego powodu programiści platformy powinni jak najszybciej przejść z Make i wdrożyć Soong. Wyślij pytania do grupy dyskusyjnej Google zajmującej się budowaniem Androida, aby uzyskać pomoc.

Co to jest Soong?

System kompilacji Soong został wprowadzony w systemie Android 7.0 (Nougat), aby zastąpić Make. Wykorzystuje narzędzie do klonowania Kati GNU Make i komponent systemu kompilacji Ninja w celu przyspieszenia kompilacji Androida.

Zobacz opis Android Make Build System w Android Open Source Project (AOSP), aby uzyskać ogólne instrukcje i zmiany systemu kompilacji dla twórców Android.mk, aby dowiedzieć się o modyfikacjach potrzebnych do adaptacji z Make na Soong.

Zobacz wpisy dotyczące kompilacji w glosariuszu, aby znaleźć definicje kluczowych terminów, a pliki referencyjne Soong, aby uzyskać szczegółowe informacje.

Porównanie marki i Soong

Oto porównanie konfiguracji Make z Soongiem wykonującym to samo w pliku konfiguracyjnym Soong (Blueprint lub .bp ).

Daj przykład

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)

Świetny przykład

cc_library_shared {
     name: “libxmlrpc++”,

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

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

Zobacz Simple Build Configuration, aby zapoznać się z przykładami konfiguracji Soong dla konkretnych testów.

Format pliku Android.bp

Z Android.bp pliki Android.bp są proste. Nie zawierają warunków ani instrukcji sterowania przepływem; cała złożoność jest obsługiwana przez logikę budowania napisaną w Go. Jeśli to możliwe, składnia i semantyka plików Android.bp są podobne do plików Bazel BUILD .

Moduły

Moduł w pliku Android.bp zaczyna się od typu modułu, po którym następuje zestaw właściwości w name: "value", format:

cc_binary {
    name: "gzip",
    srcs: ["src/test/minigzip.c"],
    shared_libs: ["libz"],
    stl: "none",
}

Każdy moduł musi mieć właściwość name , a wartość musi być unikalna we wszystkich plikach Android.bp , z wyjątkiem wartości właściwości name w przestrzeniach nazw i wstępnie skompilowanych modułach, które mogą się powtarzać.

Właściwość srcs określa pliki źródłowe użyte do zbudowania modułu jako listę ciągów. Możesz odwołać się do danych wyjściowych innych modułów, które tworzą pliki źródłowe, takie jak genrule lub filegroup , przy użyciu składni odwołania do modułu ":<module-name>" .

Aby uzyskać listę prawidłowych typów modułów i ich właściwości, zobacz dokumentację modułów Soong .

Rodzaje

Zmienne i właściwości są silnie wpisane, zmienne są dynamicznie oparte na pierwszym przypisaniu, a właściwości są ustawiane statycznie według typu modułu. Obsługiwane typy to:

  • Wartości logiczne ( true lub false )
  • Całkowitymi ( int )
  • Ciągi "string" ( "string" )
  • Listy ciągów ( ["string1", "string2"] )
  • Mapy ( {key1: "value1", key2: ["value2"]} )

Mapy mogą zawierać wartości dowolnego typu, w tym mapy zagnieżdżone. Listy i mapy mogą mieć końcowe przecinki po ostatniej wartości.

Globy

Właściwości, które pobierają listę plików, takie jak srcs , mogą również przyjmować wzorce srcs . Wzorce glob mogą zawierać zwykłe symbole wieloznaczne * systemu UNIX, na przykład *.java . Wzorce Glob mogą również zawierać pojedynczy ** symbol wieloznaczny jako element ścieżki, który pasuje do zera lub większej liczby elementów ścieżki. Na przykład java/**/*.java dopasowuje zarówno java/Main.java i java/com/android/Main.java .

Zmienne

Plik Android.bp może zawierać przypisania zmiennych najwyższego poziomu:

gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
    name: "gzip",
    srcs: gzip_srcs,
    shared_libs: ["libz"],
    stl: "none",
}

Zakres zmiennych obejmuje pozostałą część pliku, w którym są zadeklarowane, a także wszystkie podrzędne pliki Blueprint. Zmienne są niezmienne z jednym wyjątkiem: można do nich dołączyć przypisanie += , ale tylko przed odniesieniem do nich.

Komentarze

Pliki Android.bp mogą zawierać komentarze wielowierszowe /* */ stylu C oraz jednowierszowe // komentarze w stylu C ++.

Operatorzy

Łańcuchy, listy łańcuchów i mapy można dołączać za pomocą operatora +. Liczby całkowite można zsumować za pomocą operatora + . Dołączenie mapy tworzy sumę kluczy w obu mapach, dołączając wartości kluczy, które są obecne w obu mapach.

Warunki

Soong nie obsługuje warunków warunkowych w plikach Android.bp . Zamiast tego złożoność reguł kompilacji, które wymagałyby warunków warunkowych, jest obsługiwana w Go, gdzie można używać funkcji języka wysokiego poziomu i można śledzić niejawne zależności wprowadzone przez warunki warunkowe. Większość warunków warunkowych jest konwertowana na właściwość mapy, w której jedna z wartości mapy jest wybierana i dołączana do właściwości najwyższego poziomu.

Na przykład, aby obsługiwać pliki specyficzne dla architektury:

cc_library {
    ...
    srcs: ["generic.cpp"],
    arch: {
        arm: {
            srcs: ["arm.cpp"],
        },
        x86: {
            srcs: ["x86.cpp"],
        },
    },
}

Formatter

Soong zawiera kanoniczny program formatujący dla plików Blueprint, podobny do gofmt . Aby rekurencyjnie sformatować wszystkie pliki Android.bp w bieżącym katalogu, uruchom:

bpfmt -w .

Format kanoniczny obejmuje wcięcia z czterema spacjami, nowe wiersze po każdym elemencie listy zawierającej wiele elementów oraz przecinek na końcu list i map.

Moduły specjalne

Niektóre specjalne grupy modułów mają unikalne cechy.

Domyślne moduły

Moduł defaults może służyć do powtarzania tych samych właściwości w wielu modułach. Na 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 pozwalają modułowi mieć taką samą nazwę jak jego odpowiedniki oparte na źródłach. Na przykład może istnieć plik cc_prebuilt_binary nazwie foo gdy istnieje już plik cc_binary o tej samej nazwie. Daje to programistom elastyczność w wyborze wersji, która ma być zawarta w produkcie końcowym. Jeśli konfiguracja kompilacji zawiera obie wersje, wartość flagi prefer w definicji wstępnie utworzonego modułu określa, która wersja ma priorytet. Zwróć uwagę, że niektóre wstępnie skompilowane moduły mają nazwy, które nie rozpoczynają się od prebuilt , na przykład android_app_import .

Moduły przestrzeni nazw

Do czasu pełnej konwersji systemu Android z Make na Soong, konfiguracja produktu Make musi określać wartość PRODUCT_SOONG_NAMESPACES . Jego wartością powinna być rozdzielona spacjami lista przestrzeni nazw, które Soong eksportuje do programu Make w celu zbudowania za pomocą polecenia m . Po zakończeniu konwersji Androida na Soong szczegóły włączania przestrzeni nazw mogą ulec zmianie.

Soong umożliwia modułom w różnych katalogach określenie tej samej nazwy, o ile każdy moduł jest zadeklarowany w oddzielnej przestrzeni nazw. Przestrzeń nazw można zadeklarować w następujący sposób:

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

Zauważ, że przestrzeń nazw nie ma właściwości name; jego ścieżka jest automatycznie przypisywana jako jego nazwa.

Każdemu modułowi Soong jest przypisana przestrzeń nazw w oparciu o jego lokalizację w drzewie. Uważa się, że każdy moduł Soong znajduje się w przestrzeni nazw zdefiniowanej przez soong_namespace znajdującą się w pliku Android.bp w bieżącym katalogu lub najbliższym katalogu Android.bp . Jeśli taki moduł soong_namespace zostanie znaleziony, uznaje się, że moduł znajduje się w niejawnej głównej przestrzeni nazw.

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…

  1. Następnie, jeśli D jest w pełni kwalifikowaną nazwą w postaci //namespace:module , przeszukiwana jest tylko określona przestrzeń nazw pod kątem określonej nazwy modułu.
  2. W przeciwnym razie Soong najpierw szuka modułu o nazwie D zadeklarowanego w przestrzeni nazw N.
  3. Jeśli ten moduł nie istnieje, Soong szuka modułu o nazwie D w przestrzeniach nazw I1, I2, I3…
  4. Na koniec Soong szuka w głównej przestrzeni nazw.