Moduły Rust na Androida

Ogólnie definicje modułów rust_* są zgodne z oczekiwaniami użytkowników i sposobami wykorzystywania cc_*. Oto przykład definicji modułu dla binarnego pliku Rust:

rust_binary {
    name: "hello_rust",
    crate_name: "hello_rust",
    srcs: ["src/hello_rust.rs"],
    host_supported: true,
}

Na tej stronie znajdziesz informacje o najczęstszych właściwościach modułów rust_*. Więcej informacji o konkretnych typach modułów i przykładowych definicjach modułów znajdziesz w artykułach Moduły binarne, Moduły bibliotekiModuły testowe.

Podstawowe typy modułów

TypDefinicjaWięcej informacji
rust_binaryPlik binarny Rust Moduły binarne strona
rust_libraryTworzy bibliotekę Rust i zapewnia wersje rlibdylib. rust_library, strona Moduły w bibliotece.
rust_ffiTworzy bibliotekę C Rust, której można używać w modułach cc. Zapewnia ona zarówno wersje statyczne, jak i współdzielone. rust_ffi, strona Komponenty w bibliotece
rust_proc_macroTworzy bibliotekę proc-macro w języku Rust. (są one analogiczne do wtyczek kompilatora). rust_proc_macro, strona Biblioteki Modułów
rust_testTworzy testowy binarny plik Rust, który korzysta ze standardowego zestawu testów Rust. Strona Testowanie modułów
rust_fuzzTworzy binarny plik fuzzingu Rust, korzystając z libfuzzer. rust_fuzz – przykład modułu
rust_protobufGeneruje kod źródłowy i tworzy bibliotekę Rust, która udostępnia interfejs dla konkretnego protobufa. strony Protobufs ModulesGenerators of Source.
rust_bindgenGeneruje kod źródłowy i tworzy bibliotekę Rust zawierającą wiązania Rust do bibliotek C. strony Moduły bindgen bindingsGenerowanie źródeł.

Ważne właściwości wspólne

Te właściwości są wspólne dla wszystkich modułów Rust na Androida. Wszystkie dodatkowe (wyjątkowe) właściwości powiązane z poszczególnymi modułami Rust są wymienione na stronie danego modułu.

nazwa

name to nazwa modułu. Podobnie jak w przypadku innych modułów Soong, musi on być unikalny w przypadku większości typów modułów Android.bp. Domyślnie jako nazwa pliku wyjściowego jest używana wartość name. Jeśli nazwa pliku wyjściowego musi być inna niż nazwa modułu, użyj właściwości stem, aby ją zdefiniować.

łodyga

stem (opcjonalnie) umożliwia bezpośrednią kontrolę nazwy wyjściowego pliku (z wyjątkiem rozszerzenia pliku i innych sufiksów). Na przykład biblioteka rust_library_rlib z wartością rdzenia libfoo wygeneruje plik libfoo.rlib. Jeśli nie podasz wartości właściwości stem, nazwa pliku wyjściowego przyjmie domyślnie nazwę modułu.

Użyj funkcji stem, jeśli nie możesz ustawić nazwy modułu jako żądanej nazwy pliku wyjściowego. Na przykład rust_library dla skrzynki log ma nazwę liblog_rust, ponieważ skrzynka liblog cc_library już istnieje. W tym przypadku użycie właściwości stem spowoduje, że plik wyjściowy będzie miał nazwę liblog.* zamiast liblog_rust.*.

srcs

srcs zawiera pojedynczy plik źródłowy, który reprezentuje punkt wejścia do modułu (zwykle main.rs lub lib.rs). rustc obsługuje rozdzielczość i wykrywanie wszystkich innych plików źródłowych wymaganych do kompilacji, które są wymienione w wygenerowanym pliku deps.

W miarę możliwości unikaj używania tego kodu w kodzie platformy. Więcej informacji znajdziesz w artykule Generatory kodu.

crate_name

crate_name ustawia metadane nazwy skrzynki za pomocą flagi rustc --crate_name. W przypadku modułów, które generują biblioteki, ta wartość musi odpowiadać oczekiwanej nazwie kontenera użytej w źródle. Jeśli na przykład moduł libfoo_bar jest w źródle oznaczony jako extern crate foo_bar, musi być to crate_name: "foo_bar".

Ta właściwość jest wspólna dla wszystkich modułów rust_*, ale jest wymagana w przypadku modułów, które generują biblioteki Rust (takich jak rust_library rust_ffi, rust_bindgen, rust_protobufrust_proc_macro). Te moduły narzucają wymagania rustc dotyczące relacji między crate_name a nazwa pliku wyjściowego. Więcej informacji znajdziesz w sekcji Moduły biblioteki.

lints

Rustc linter jest domyślnie uruchamiany w przypadku wszystkich typów modułów z wyjątkiem generatorów źródła. Niektóre zestawy lint są definiowane i używane do sprawdzania kodu źródłowego modułu. Możliwe wartości takich zestawów reguł lint:

  • default domyślny zestaw narzędzi lint, zależny od lokalizacji modułu.
  • android najsurowsze ustawienia lint, które mają zastosowanie do całego kodu platformy Android
  • vendor zrelaksowany zestaw narzędzi do sprawdzania kodu dostawcy,
  • none – ignorowanie wszystkich ostrzeżeń i błędów lint

clippy_lints

Domyślnie Clippy Linter jest też uruchamiany w przypadku wszystkich typów modułów z wyjątkiem generatorów źródeł. Zdefiniowano kilka zestawów narzędzi lint służących do sprawdzania źródła modułu. Oto możliwe wartości:

  • default domyślny zestaw narzędzi lint w zależności od lokalizacji modułu
  • android najsurowsze ustawienia lint, które mają zastosowanie do całego kodu platformy Android
  • vendor zrelaksowany zestaw narzędzi do sprawdzania kodu dostawcy,
  • none – ignorowanie wszystkich ostrzeżeń i błędów lint

wydanie

edition określa wersję Rust używaną do kompilowania tego kodu. Jest to podobne do wersji standardowych w językach C i C++. Dopuszczalne wartości to 2015, 20182021 (domyślna).

flagi

flags zawiera listę ciągów znaków z opcjami, które mają zostać przekazane do rustc podczas kompilacji.

ld_flags

ld-flags zawiera listę ciągów znaków z flagami, które mają być przekazywane linkerowi podczas kompilowania źródła. Są one przekazywane przez flagę -C linker-args rustc. clang jest używany jako front-end łącznika, wywołując lld do faktycznego łączenia.

Funkcje

features to lista ciągów znaków funkcji, które muszą być włączone podczas kompilacji. --cfg 'feature="foo"' przekazuje ten argument do rustc. Większość funkcji jest nakładowa, więc w wielu przypadkach obejmuje ona pełny zestaw funkcji wymaganych przez wszystkie zależne moduły. W przypadku funkcji, które się wykluczają, zdefiniuj dodatkowe moduły w plikach kompilacji, które zapewniają funkcje sprzeczne.

cfgs

cfgs zawiera listę ciągów znaków z flagami cfg, które mają być włączone podczas kompilacji. rustc otrzymuje te dane od --cfg foo--cfg "fizz=buzz".

System kompilacji automatycznie ustawia określone flagi cfg w określonych sytuacjach:

  • Moduły utworzone jako dylib będą miały ustawiony parametr android_dylib cfg.

  • W przypadku modułów, które korzystają z VNDK, będzie ustawiony plik android_vndk.cfg. Jest to podobne do definicji funkcji __ANDROID_VNDK__ w C++.

rozbieranie się

strip określa, czy i jak plik wyjściowy ma być pozbawiony informacji (w odpowiednich przypadkach). Jeśli to ustawienie nie jest ustawione, moduły urządzenia domyślnie usuwają wszystko oprócz mini debuginfo. Domyślnie moduły hosta nie usuwają żadnych symboli. Dozwolone wartości to none do wyłączenia usuwania i all do usunięcia wszystkiego, w tym mini debuginfo. Dodatkowe wartości znajdziesz w dokumentacji modułów Song.

host_supported

W przypadku modułów urządzeń parametr host_supported wskazuje, czy moduł powinien również udostępniać wariant hosta.

Definiowanie zależności bibliotek

Moduły Rust mogą zależeć zarówno od bibliotek CC, jak i Rust za pomocą tych właściwości:

Nazwa usługi Opis
rustlibs Lista modułów rust_library, które są też zależnościami. Użyj tej metody do deklarowania zależności, ponieważ pozwala systemowi kompilacji wybrać preferowane powiązanie. (patrz poniżej sekcja o linkowaniu do bibliotek Rust)
rlibs Lista modułów rust_library, które muszą być połączone statycznie jako rlibs. (Używaj z ostrożnością; patrz poniżej Używanie linków do bibliotek Rust).
shared_libs Lista modułów cc_library, które muszą być dynamicznie powiązane jako zasoby wspólne.
static_libs Lista modułów cc_library, które muszą być połączone statycznie jako biblioteki statyczne.
whole_static_libs Lista modułów cc_library, które powinny być połączone statycznie jako biblioteki statyczne i włączone w całości do biblioteki wynikowej. W przypadku wariantów rust_ffi_static w archiwum biblioteki statycznej uwzględnione zostaną warianty whole_static_libraries. W przypadku wariantów rust_library_rlib biblioteki whole_static_libraries zostaną połączone w powstałą bibliotekę rlib.

Podczas tworzenia linków do bibliotek Rust zalecamy używanie właściwości rustlibs zamiast rlibs lub dylibs, chyba że masz konkretny powód, aby tego nie robić. Pozwala to systemowi kompilacji wybrać prawidłowe połączenie na podstawie wymagań modułu głównego i zmniejsza prawdopodobieństwo, że drzewo zależności będzie zawierać wersje rlibdylib biblioteki (co spowoduje niepowodzenie kompilacji).

Nieobsługiwane i ograniczone funkcje kompilacji

Soong Rust zapewnia ograniczone wsparcie dla obrazów i zrzutów ekranu vendorvendor_ramdisk. Obsługiwane są jednak wartości staticlibs, cdylibs, rlibsbinaries. W przypadku docelowych wartości dostawcy dotyczących tworzenia obrazów jest ustawiona właściwość android_vndk cfg. Możesz użyć tego w kodzie, jeśli występują różnice między wartościami docelowymi systemu a dostawcy. rust_proc_macros nie są przechwytywane w ramach migawek dostawcy. Jeśli są one zależne, należy odpowiednio je kontrolować.

Obrazy produktu, VNDK i odzyskiwania nie są obsługiwane.

Kompilacje przyrostowe

Deweloperzy mogą włączyć kompilację przyrostową kodu źródłowego Rust, ustawiając zmienną środowiskową SOONG_RUSTC_INCREMENTAL na true.

Ostrzeżenie: nie ma gwarancji, że pliki binarne będą identyczne z tymi wygenerowanymi przez buildboty. Adresy funkcji lub danych zawartych w plikach obiektów mogą się różnić. Aby mieć pewność, że wygenerowane artefakty są w 100% identyczne z tymi utworzonymi przez infrastrukturę EngProd, pozostaw tę wartość pustą.