Moduły Androida w języku Rust

Ogólnie definicje modułów rust_* są zgodne z oczekiwaniami użytkowników i sposobami korzystania z 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 przedstawiamy najczęstsze właściwości 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 bibliotek i Moduły testowe.

Podstawowe typy modułów

TypDefinicjaWięcej informacji
rust_binaryPlik binarny Rust Strona Moduły binarne
rust_libraryTworzy bibliotekę Rust i zawiera warianty rlibdylib. rust_library, strona Moduły w bibliotece.
rust_ffiTworzy bibliotekę Rust C, której można używać w modułach DW, i udostępnia zarówno warianty statyczne, jak i udostępnione. rust_ffi, strona Komponenty w bibliotece
rust_proc_macroTworzy bibliotekę proc-macro Rust. (są one analogiczne do wtyczek kompilatora). rust_proc_macro, strona Moduły bibliotek
rust_testTworzy testowy binarny plik Rust, który korzysta ze standardowego zestawu testów Rust. Strona Moduły testowe
rust_fuzzGeneruje binarny plik Rust z wykorzystaniem funkcji fuzz libfuzzer. rust_fuzz – przykład modułu
rust_protobufGeneruje kod źródłowy i tworzy bibliotekę Rust, która zapewnia interfejs dla konkretnego protobufa. strony Protobufs Modules i Source Generators.
rust_bindgenGeneruje kod źródłowy i tworzy bibliotekę Rust zawierającą wiązania Rust do bibliotek C. strony Moduły bindgenGenerowanie źródeł.

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

Te właściwości są wspólne we wszystkich modułach Androida Rust. Wszelkie dodatkowe (unikalne) właściwości powiązane z poszczególnymi modułami Rust są wymienione na stronie tego 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 nazwa pliku wyjściowego to 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 (opcjonalny) zapewnia bezpośrednią kontrolę nad nazwą pliku wyjściowego (bez 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.

Jeśli nie możesz ustawić żądanej nazwy pliku wyjściowego, użyj funkcji stem. Na przykład rust_library dla skrzyni log nazywa się liblog_rust, bo liblog cc_library już istnieje. Dzięki użyciu w tym przypadku właściwości stem plik wyjściowy ma nazwę liblog.*, a nie liblog_rust.*.

Źródła

srcs zawiera jeden plik źródłowy reprezentujący 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. Są one wyliczane w generowanym pliku deps.

Jeśli to możliwe, unikaj takiego użycia w przypadku kodu platformy. Więcej informacji znajdziesz na stronie Generatory generatorów źródłowych.

crate_name

crate_name ustawia metadane nazwy skrzynki za pomocą flagi rustc --crate_name. W przypadku modułów, które tworzą biblioteki, ta wartość musi być zgodna z oczekiwaną nazwą skrzynki używaną 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 wymagana w przypadku modułów tworzących biblioteki Rust (takich jak rust_library rust_ffi, rust_bindgen, rust_protobuf i rust_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 biblioteczne.

linty

Moduł rustc linter jest uruchamiany domyślnie w przypadku wszystkich typów modułów z wyjątkiem generatorów źródeł. 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 lintów 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, aby ignorować wszystkie ostrzeżenia i błędy dotyczące lintowania

klippy_lint

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 do sprawdzania kodu, które służą do sprawdzania źródła modułu. Oto kilka możliwych 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, aby ignorować wszystkie ostrzeżenia i błędy dotyczące lintowania

wydanie

edition określa wersję Rust, która ma być używana do skompilowania tego kodu. Jest to podobne do wersji standardowych w językach C i C++. Dopuszczalne wartości to 20152018 (domyślna).

flagi

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

flagi_ld

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 tagu łączącego, wywołując lld do faktycznego łączenia.

Funkcje

features to ciąg znaków listy 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 moduły zależne. W przypadku funkcji, które się wykluczają, zdefiniuj dodatkowe moduły w plikach kompilacji, które zapewniają funkcje sprzeczne.

cfG

cfgs zawiera listę flag 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 konkretnych sytuacjach:

  • Moduł skompilowany jako dylib będzie miał ustawiony parametr android_dylib cfg.

  • Moduły, które korzystają z VNDK, będą miały ustawiony plik android_vndk.cfg. Jest to podobne do definicji __ANDROID_VNDK__ dla C++.

rozbieranie się

strip określa, czy i w jaki sposób plik wyjściowy ma być usuwany (jeśli ma to zastosowanie). Jeśli zasada jest nieskonfigurowana, moduły urządzenia domyślnie usuwają wszystko oprócz minidebugowania. Moduły hosta domyślnie nie usuwają żadnych symboli. Prawidłowe wartości to none, jeśli chcesz wyłączyć usuwanie, lub all – usuwa wszystko, w tym minidebuginfo. Dodatkowe wartości znajdziesz w dokumentacji modułów Soong.

host_supported

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

Zdefiniuj zależności biblioteki

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żywaj tej metody jako preferowanej metody deklarowania zależności, ponieważ umożliwia systemowi kompilacji wybranie preferowanego połączenia. (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 zostaną połączone biblioteki whole_static_libraries w wynikowej bibliotece rlib.

W przypadku łączenia z bibliotekami Rust najlepiej jest używać właściwości rustlibs, a nie rlibs lub dylibs, chyba że masz konkretny powód. Dzięki temu system kompilacji może wybrać odpowiednie połączenie na podstawie wymagań modułu głównego. Zmniejsza to ryzyko, że drzewo zależności będzie zawierać zarówno wersję rlib, jak i dylib biblioteki (co spowoduje błąd kompilacji).

Nieobsługiwane i ograniczone funkcje kompilacji

Usługa Rust firmy Soong zapewnia ograniczoną obsługę obrazów i zrzutów vendor oraz vendor_ramdisk. Obsługiwane są jednak staticlibs, cdylibs, rlibsbinaries. W przypadku docelowych wersji obrazu dostawcy ustawiona jest właściwość android_vndk cfg. Możesz go użyć w kodzie, jeśli występują różnice między celami systemowymi a celami dostawcy. rust_proc_macros nie są przechwytywane w ramach zrzutów od dostawców. Jeśli są od nich zależne, zadbaj o odpowiednią kontrolę wersji.

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

Kompilacje przyrostowe

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

Ostrzeżenie: nie gwarantuje to utworzenia plików binarnych identycznych z wygenerowanych przez roboty Buildbot. 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ą.