Moduły Rust na Androida

Ogólnie rzecz biorąc, rust_*definicje modułów są ściśle powiązane zcc_* ich zastosowaniem i oczekiwaniami. Oto przykład definicji modułu dla pliku binarnego 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 sekcjach Moduły binarne, Moduły bibliotekModuły testowe.

Podstawowe typy modułów

TypDefinicjaWięcej informacji
rust_binaryplik binarny Rust, Moduły binarne strona
rust_libraryTworzy bibliotekę Rust i udostępnia warianty rlibdylib. rust_librarystrona Moduły biblioteki.
rust_ffiTworzy bibliotekę C w języku Rust, która może być używana przez moduły cc, i udostępnia warianty statyczne i współdzielone. rust_ffi Strona Moduły biblioteki
rust_proc_macroTworzy bibliotekę proc-macro Rust. (Są one analogiczne do wtyczek kompilatora). rust_proc_macro Strona Moduły bibliotek
rust_testTworzy binarny plik testowy Rust, który korzysta ze standardowego środowiska testowego Rust. Strona Testowanie modułów
rust_fuzzTworzy binarny program do fuzzingu w Rust, który korzysta z libfuzzer. Przykład modułu rust_fuzz
rust_protobufGeneruje źródło i tworzy bibliotekę Rust, która udostępnia interfejs dla określonego protokołu protobuf. strony Protobufs ModulesSource Generators;
rust_bindgenGeneruje kod źródłowy i tworzy bibliotekę Rust zawierającą powiązania Rust z bibliotekami C. Bindgen Bindings ModulesSource Generators

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

Te właściwości są wspólne dla wszystkich modułów Rust na Androidzie. Wszelkie dodatkowe (unikalne) właściwości powiązane z poszczególnymi modułami Rusta są wymienione na stronie danego modułu.

nazwa

name to nazwa modułu. Podobnie jak w przypadku innych modułów Soong, musi być on unikalny w większości Android.bp typów modułów. Domyślnie jako nazwa pliku wyjściowego używana jest 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średnie sterowanie nazwą pliku wyjściowego (z wyjątkiem rozszerzenia pliku i innych sufiksów). Na przykład biblioteka rust_library_rlib o wartości podstawowej libfoo generuje plik libfoo.rlib. Jeśli nie podasz wartości właściwości stem, nazwa pliku wyjściowego domyślnie przyjmie nazwę modułu.

Użyj funkcji stem, gdy nie możesz ustawić nazwy modułu na żądaną nazwę pliku wyjściowego. Na przykład rust_library dla skrzyni log ma nazwę liblog_rust, ponieważ liblog cc_library już istnieje. Użycie w tym przypadku właściwości stem gwarantuje, że plik wyjściowy będzie miał nazwę liblog.*, a nie liblog_rust.*.

srcs

srcs zawiera jeden plik źródłowy, który reprezentuje punkt wejścia do modułu (zwykle main.rs lub lib.rs). rustc obsługuje rozpoznawanie 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 tego w przypadku kodu platformy. Więcej informacji znajdziesz w sekcji Generatory kodu źródłowego.

crate_name

crate_name ustawia metadane nazwy pakietu za pomocą flagi rustc --crate_name. W przypadku modułów, które tworzą biblioteki, ta nazwa musi odpowiadać oczekiwanej nazwie pakietu używanej w kodzie źródłowym. Jeśli na przykład moduł libfoo_bar jest przywoływany w kodzie źródłowym jako extern crate foo_bar, to musi być 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 tworzą biblioteki Rust (takie jak rust_library, rust_ffi, rust_bindgen, rust_protobufrust_proc_macro). Te moduły wymuszają wymagania rustc dotyczące relacji między crate_name a nazwą pliku wyjściowego. Więcej informacji znajdziesz w sekcji Moduły biblioteki.

lints

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

  • default domyślny zestaw lintów w zależności od lokalizacji modułu;
  • android najbardziej rygorystyczny zestaw reguł lint, który ma zastosowanie do całego kodu platformy Androida;
  • vendor zastosowano mniej rygorystyczny zestaw reguł do kodu dostawcy;
  • none, aby zignorować wszystkie ostrzeżenia i błędy lint

clippy_lints

Linter clippy jest też domyślnie uruchamiany w przypadku wszystkich typów modułów z wyjątkiem generatorów kodu źródłowego. Zdefiniowano kilka zestawów lintów, które służą do sprawdzania kodu źródłowego modułu. Oto niektóre możliwe wartości:

  • default domyślny zestaw lintów zależny od lokalizacji modułu;
  • android najbardziej rygorystyczny zestaw reguł lint, który ma zastosowanie do całego kodu platformy Androida;
  • vendor zastosowano mniej rygorystyczny zestaw reguł do kodu dostawcy;
  • none, aby zignorować wszystkie ostrzeżenia i błędy lint

wydanie

edition określa wersję Rusta, która ma być używana do kompilowania tego kodu. Jest to podobne do wersji std w przypadku języków C i C++. Prawidłowe wartości to 2015, 20182021 (domyślnie).

flagi,

flags zawiera listę ciągów znaków z flagami, które mają być przekazywane do rustc podczas kompilacji.

ld_flags

ld-flags zawiera listę ciągów znaków z flagami, które mają być przekazywane do linkera podczas kompilowania kodu źródłowego. Są one przekazywane przez flagę -C linker-args rustc. clang jest używany jako interfejs linkera, który wywołuje lld w celu faktycznego połączenia.

Funkcje

features to lista ciągów znaków z nazwami funkcji, które muszą być włączone podczas kompilacji. Jest on przekazywany do rustc przez --cfg 'feature="foo"'. Większość funkcji jest dodatkowa, więc w wielu przypadkach jest to pełny zestaw funkcji wymaganych przez wszystkie moduły zależne. Jeśli jednak funkcje są wzajemnie wykluczające się, zdefiniuj dodatkowe moduły w plikach kompilacji, które zapewniają sprzeczne funkcje.

cfgs

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

System kompilacji automatycznie ustawia określone flagi cfg w określonych sytuacjach, które wymieniamy poniżej:

  • Moduły utworzone jako biblioteka dylib będą miały ustawioną wartość android_dylib cfg.

  • Moduły, które będą korzystać z VNDK, będą miały ustawioną wartość android_vndk cfg. Jest to podobne do definicji __ANDROID_VNDK__ w C++.

rozbieranie się

strip określa, czy i jak plik wyjściowy jest usuwany (w odpowiednich przypadkach). Jeśli to ustawienie nie jest skonfigurowane, moduły urządzenia domyślnie usuwają wszystko z wyjątkiem mini debuginfo. Domyślnie moduły hosta nie usuwają żadnych symboli. Prawidłowe wartości to none (aby wyłączyć usuwanie) i all (aby usunąć wszystko, w tym mini debuginfo). Dodatkowe wartości znajdziesz w dokumentacji modułów Soong.

host_supported

W przypadku modułów urządzenia parametr host_supported wskazuje, czy moduł powinien też udostępniać wariant hosta.

Określanie zależności biblioteki

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

Nazwa usługi Opis
rustlibs Lista modułów rust_library, które są również zależnościami. Używaj tej metody jako preferowanego sposobu deklarowania zależności, ponieważ umożliwia ona systemowi kompilacji wybór preferowanego połączenia. (Patrz sekcja Łączenie z bibliotekami Rust poniżej).
rlibs Lista modułów rust_library, które muszą być statycznie połączone jako rlibs. (Używaj ostrożnie; patrz sekcja Łączenie z bibliotekami Rust poniżej).
shared_libs Lista modułów cc_library, które muszą być dynamicznie połączone jako biblioteki współdzielone.
static_libs Lista modułów cc_library, które muszą być statycznie połączone jako biblioteki statyczne.
whole_static_libs Lista modułów cc_library, które powinny być statycznie połączone jako biblioteki statyczne i w całości uwzględnione w bibliotece wynikowej. W przypadku wariantów rust_ffi_static w wynikowym archiwum biblioteki statycznej zostanie uwzględniony plik whole_static_libraries. W przypadku wariantów rust_library_rlib biblioteki whole_static_libraries zostaną dołączone do wynikowej biblioteki rlib.

Podczas łączenia z bibliotekami Rusta zalecamy używanie właściwości rustlibs zamiast rlibs lub dylibs, chyba że masz ku temu konkretny powód. Umożliwia to systemowi kompilacji wybór prawidłowego połączenia 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).

Funkcje kompilacji nieobsługiwane lub obsługiwane w ograniczonym zakresie

Soong's Rust oferuje ograniczone wsparcie dla obrazów i zrzutów vendor oraz vendor_ramdisk. Obsługiwane są jednak wartości staticlibs, cdylibs, rlibs i binaries. W przypadku docelowych kompilacji obrazów dostawcy ustawiona jest właściwość android_vndk cfg. Możesz użyć tego w kodzie, jeśli występują różnice między systemem a docelowymi wartościami dostawcy. rust_proc_macros nie są rejestrowane w ramach migawek dostawcy. Jeśli są od nich zależne, zadbaj o odpowiednie zarządzanie wersjami.

Obrazy produktów, VNDK i Recovery nie są obsługiwane.

Kompilacje przyrostowe

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

Ostrzeżenie: nie ma gwarancji, że wygenerowane pliki binarne będą identyczne z tymi, które tworzą roboty kompilujące. 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, które zostały utworzone przez infrastrukturę EngProd, pozostaw tę wartość nieustawioną.