Moduły Rust na Androida

Ogólnie rzecz biorąc, definicje modułów rust_* są zgodne z użyciem i oczekiwaniami dotyczącymi cc_*. Oto przykład definicji modułu dla pliku Rust binarnego:

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

Ta strona zawiera 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 na stronach Moduły binarne, Moduły bibliotek lub Moduły testowe.

Podstawowe typy modułów

TypDefinicjaWięcej informacji
rust_binaryPlik binarny Rust Strona Moduły binarne
rust_libraryTworzy bibliotekę Rust i udostępnia warianty rlib i dylib. rust_library, strona Moduły bibliotek.
rust_ffiTworzy bibliotekę Rust C, której można używać w modułach cc , i udostępnia warianty statyczne i współdzielone. rust_ffi, strona Moduły bibliotek
rust_proc_macroTworzy bibliotekę proc-macro Rust. (Są one analogiczne do wtyczek kompilatora). rust_proc_macro, strona Moduły bibliotek
rust_testTworzy plik binarny testu Rust, który korzysta ze standardowego narzędzia do testowania Rust. Strona Moduły testowe
rust_fuzzTworzy plik binarny fuzzingu Rust, który korzysta 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 protokołu protobuf. Strony Moduły Protobufs i Generatory kodu źródłowego
rust_bindgenGeneruje kod źródłowy i tworzy bibliotekę Rust zawierającą powiązania Rust z bibliotekami C. Strony Moduły powiązań Bindgen i Generatory kodu źródłowego

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

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

name

name to nazwa modułu. Podobnie jak w przypadku innych modułów Soong, musi być ona unikalna w większości typów modułów Android.bp. Domyślnie name jest używana jako nazwa pliku wyjściowego. Jeśli nazwa pliku wyjściowego musi się różnić od nazwy modułu, użyj właściwości stem.

stem

stem (opcjonalnie) umożliwia bezpośrednie sterowanie nazwą pliku wyjściowego (z wyłączeniem rozszerzenia pliku i innych sufiksów). Na przykład biblioteka rust_library_rlib z wartością właściwości stem libfoo tworzy 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 moduł rust_library dla pakietu log ma nazwę liblog_rust, ponieważ istnieje już liblog cc_library. Użycie w tym przypadku właściwości stem gwarantuje, ż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 rozpoznawanie i wykrywanie wszystkich innych plików źródłowych wymaganych do kompilacji, które są wymienione w tworzonym pliku deps.

Jeśli to możliwe, unikaj tego użycia 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 wartość musi być zgodna z oczekiwaną nazwą pakietu używaną 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 rust_* modułów, ale jest wymagana w przypadku modułów , które tworzą Rust biblioteki (takie 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 bibliotek.

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 linterów są zdefiniowane i używane do sprawdzania kodu źródłowego modułu. Możliwe wartości takich zestawów linterów:

  • default – domyślny zestaw linterów, w zależności od lokalizacji modułu.
  • android – najściślejszy zestaw linterów, który ma zastosowanie do całego kodu platformy Android.
  • vendor – luźny zestaw linterów stosowany do kodu dostawcy.
  • none – ignorowanie wszystkich ostrzeżeń i błędów linterów.

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 linterów, które są używane do sprawdzania kodu źródłowego modułu. Oto niektóre możliwe wartości:

  • default – domyślny zestaw linterów w zależności od lokalizacji modułu.
  • android – najściślejszy zestaw linterów, który ma zastosowanie do całego kodu platformy Android.
  • vendor – luźny zestaw linterów stosowany do kodu dostawcy.
  • none – ignorowanie wszystkich ostrzeżeń i błędów linterów.

edition

edition określa wersję Rust, która ma być używana do kompilowania tego kodu. Jest to podobne do wersji standardowych w przypadku C i C++. Prawidłowe wartości to 2015, 2018 i 2021 (domyślna).

flags

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 konsolidatora podczas kompilowania kodu źródłowego. Są one przekazywane przez flagę -C linker-args rustc. clang jest używany jako interfejs konsolidatora, który wywołuje lld do rzeczywistego łączenia.

features

features to lista ciągów znaków z funkcjami, które muszą być włączone podczas kompilacji. Jest ona przekazywana do rustc przez --cfg 'feature="foo"'. Większość funkcji jest addytywna, więc w wielu przypadkach składa się z pełnego zestawu funkcji wymaganych przez wszystkie moduły zależne. Jeśli jednak funkcje wykluczają się wzajemnie, zdefiniuj dodatkowe moduły w plikach kompilacji, które udostępniają sprzeczne funkcje.

cfgs

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

System kompilacji automatycznie ustawia niektóre flagi cfg w określonych sytuacjach wymienionych poniżej:

  • Moduły skompilowane jako dylib będą miały ustawioną flagę android_dylib.

  • Moduły, które używają VNDK, będą miały ustawioną flagę android_vndk. Jest to podobne do __ANDROID_VNDK__ definicji w przypadku C++.

strip

strip określa, czy i jak plik wyjściowy ma być pozbawiony symboli (jeśli dotyczy). Jeśli ta wartość nie jest ustawiona, moduły urządzenia domyślnie usuwają wszystko oprócz mini debuginfo. Moduły hosta domyślnie nie usuwają żadnych symboli. Prawidłowe wartości to none (wyłączenie usuwania symboli) i all (usunięcie wszystkiego, 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.

Definiowanie zależności bibliotek

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

Nazwa właściwości Opis
rustlibs Lista modułów rust_library, które są też zależnościami. Używaj tej właściwości jako preferowanej metody deklarowania zależności, ponieważ umożliwia ona systemowi kompilacji wybranie preferowanego połączenia. (Patrz Łą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 Łą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 wynikowej bibliotece. W przypadku rust_ffi_static wariantów, whole_static_libraries zostaną uwzględnione w wynikowym archiwum biblioteki statycznej. W przypadku wariantów rust_library_rlib biblioteki whole_static_libraries zostaną spakowane w wynikowej bibliotece rlib.

Podczas łączenia z bibliotekami Rust, 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 wybranie prawidłowego połączenia na podstawie wymagań modułu głównego i zmniejsza prawdopodobieństwo, że drzewo zależności będzie zawierać wersje rlib i dylib biblioteki (co spowoduje niepowodzenie kompilacji).

Funkcje kompilacji z ograniczoną obsługą lub bez obsługi

Rust w Soong oferuje ograniczoną obsługę obrazów i migawek vendor i vendor_ramdisk. Obsługiwane są jednak staticlibs, cdylibs, rlibs i binaries. W przypadku docelowych kompilacji obrazów dostawcy ustawiana jest właściwość android_vndk cfg. Możesz jej używać w kodzie, jeśli występują różnice między systemem a celami dostawcy. rust_proc_macros nie są przechwytywane w ramach migawek dostawcy. Jeśli są one zależne, zadbaj o odpowiednią kontrolę wersji.

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

Kompilacje przyrostowe

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

Ostrzeżenie: nie gwarantuje to, że pliki binarne będą identyczne z tymi generowanymi 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, które są tworzone przez infrastrukturę EngProd, pozostaw tę wartość nieustawioną.