Módulos de Rust para Android

Como principio general, las definiciones del módulo rust_* cumplen estrictamente con el uso y las expectativas de cc_*. A continuación, se muestra un ejemplo de la definición de un módulo para un objeto binario de Rust:

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

En esta página, se describen las propiedades más comunes de los módulos rust_*. Para obtener más información sobre tipos de módulos específicos y ejemplos de definiciones de módulos, consulta las páginas Módulos de objetos binarios, Módulos de biblioteca o Módulos de prueba.

Tipos básicos de módulos

TipoDefiniciónMás información
rust_binaryUn objeto binario de Rust Página Módulos de objetos binarios
rust_libraryProduce una biblioteca de Rust y brinda variantes rlib y dylib. rust_library, en la página Módulos de biblioteca
rust_ffiProduce una biblioteca de C de Rust que pueden usar los módulos de cc y brinda variantes estáticas y compartidas. rust_ffi, en la página Módulos de biblioteca
rust_proc_macroProduce una biblioteca proc-macro de Rust. (Son similares a los complementos de compilador). rust_proc_macro, en la página Módulos de biblioteca
rust_testProduce un objeto binario de prueba de Rust que usa el agente de prueba estándar de Rust. Página Módulos de pruebas
rust_fuzzProduce un objeto binario de fuzz de Rust que aprovecha libfuzzer. Ejemplo de módulo rust_fuzz
rust_protobufGenera una fuente y produce una biblioteca de Rust que brinda una interfaz para un protobuf particular. Páginas Módulos de protobufs y Generadores de fuentes
rust_bindgenGenera una fuente y produce una biblioteca de Rust que incluye vinculaciones de Rust a bibliotecas de C. Páginas Módulos de vinculación de bindgen y Generadores de fuentes

Propiedades comunes importantes

Estas propiedades son comunes en todos los módulos de Rust para Android. Todas las propiedades adicionales (únicas) que se relacionan con módulos individuales de Rust se mencionan en la página del módulo correspondiente.

name

name es el nombre del módulo. Al igual que otros módulos de Soong, esta propiedad debe ser única en la mayoría de los tipos de módulos Android.bp. De forma predeterminada, se usa name como nombre del archivo de salida. Si el nombre del archivo de salida debe ser diferente al nombre del módulo, usa la propiedad stem para definirlo.

stem

stem (opcional) brinda control directo sobre el nombre de archivo de salida (excepto la extensión de archivo y otros sufijos). Por ejemplo, una biblioteca rust_library_rlib con un valor stem de libfoo produce un archivo libfoo.rlib. Si no brindas un valor para la propiedad stem, el nombre de archivo de salida adoptará, de forma predeterminada, el nombre del módulo.

Usa la función stem cuando no puedas establecer el nombre de módulo como el nombre de archivo de salida deseado. Por ejemplo, para el contenedor log, rust_library se llama liblog_rust, porque ya existe liblog cc_library. En este caso, usar la propiedad stem garantiza que el archivo de salida se llame liblog.* en lugar de liblog_rust.*.

srcs

srcs incluye un único archivo de fuente que representa el punto de entrada al módulo (por lo general, main.rs o lib.rs). rustc controla la resolución y la detección de todos los demás archivos de fuentes que se necesitan para la compilación. Estos se enumeran en el archivo deps que se produce.

Cuando sea posible, evita este uso para el código de la plataforma. Si deseas obtener más información, consulta Generadores de fuentes.

crate_name

crate_name establece los metadatos del nombre de contenedor a través de la marca rustc --crate_name. Para los módulos que producen bibliotecas, esta propiedad debe coincidir con el nombre de contenedor esperado que se usa en la fuente. Por ejemplo, si se hace referencia al módulo libfoo_bar en la fuente como extern crate foo_bar, este módulo debe ser crate_name: "foo_bar".

Esta propiedad es común para todos los módulos rust_*, pero es obligatoria para los módulos que producen bibliotecas de Rust (por ejemplo, rust_library, rust_ffi, rust_bindgen, rust_protobuf y rust_proc_macro). Estos módulos aplican de manera forzosa los requisitos de rustc para la relación entre crate_name y el nombre de archivo de salida. Para obtener más información, consulta la sección Módulos de biblioteca.

lints

rustc linter se ejecuta, de forma predeterminada, para todos los tipos de módulos, excepto los generadores de fuentes. Algunos conjuntos de lint se definen y se usan para validar la fuente del módulo. Los valores posibles para esos conjuntos de lint son los siguientes:

  • default (el conjunto predeterminado de lints, según la ubicación del módulo)
  • android (el conjunto de lint más estricto que se aplica a todo el código de la plataforma de Android)
  • vendor (un conjunto relajado de lints que se aplica al código del proveedor)
  • none (ignora todas las advertencias y todos los errores de lint)

clippy_lints

clippy linter también se ejecuta, de forma predeterminada, para todos los tipos de módulos, excepto los generadores de fuentes. Se definen algunos conjuntos de lints que se usan para validar la fuente del módulo. Estos son algunos valores posibles:

  • default (el conjunto predeterminado de lints, según la ubicación del módulo)
  • android (el conjunto de lint más estricto que se aplica a todo el código de la plataforma de Android)
  • vendor (un conjunto relajado de lints que se aplica al código del proveedor)
  • none (ignora todas las advertencias y todos los errores de lint)

edition

edition define la edición de Rust que se usará para compilar este código. Es similar a las versiones estándar para C y C++. Los valores válidos son 2015 y 2018 (predeterminados).

flags

flags incluye una lista de strings de marcas para pasar a rustc durante la compilación.

ld_flags

ld-flags incluye una lista de strings de marcas para pasar al vinculador cuando se compila la fuente. La marca -C linker-args de rustc pasa estas marcas. clang se usa como el frontend del vinculador, que invoca a lld para la vinculación real.

funciones

features es una lista de strings de funciones que se deben habilitar durante la compilación. --cfg 'feature="foo"' pasa esta propiedad a rustc. La mayoría de las funciones son adicionales, por lo que, en muchos casos, esta propiedad consiste en el conjunto completo de funciones que requieren todos los módulos dependientes. Sin embargo, en los casos en que las funciones sean exclusivas entre sí, define los módulos adicionales en cualquier archivo de compilación que brinde funciones que generen conflictos.

cfgs

cfgs incluye una lista de strings de marcas cfg que se habilitará durante la compilación. --cfg foo y --cfg "fizz=buzz" la pasan a rustc.

El sistema de compilación establece automáticamente ciertas marcas cfg en situaciones particulares, que se enumeran a continuación:

  • Los módulos compilados como dylib tendrán establecido el cfg android_dylib.

  • Los módulos que usaban VNDK tendrán establecido el cfg android_vndk. Esto es similar a la definición de __ANDROID_VNDK__ para C++.

strip

strip controla si se quita el archivo de salida y cómo se realiza (si corresponde). Si no se configura, los módulos de dispositivo quitarán automáticamente todo, excepto mini debuginfo. De forma predeterminada, los módulos de host no quitan ningún símbolo. Los valores válidos incluyen none para inhabilitar la eliminación y all para quitar todo, lo que incluye mini debuginfo. Puedes encontrar valores adicionales en la Referencia de módulos de Soong.

host_supported

Para los módulos de dispositivo, el parámetro host_supported indica si el módulo también debe proporcionar una variante de host.

Cómo definir dependencias de la biblioteca

Los módulos de Rust pueden depender de las bibliotecas de CC y de Rust mediante las siguientes propiedades:

Nombre de propiedad Descripción
rustlibs Lista de módulos rust_library que también son dependencias. Úsala como el método preferido para declarar dependencias, ya que permite que el sistema de compilación seleccione la vinculación que prefieras. (Consulta Cuando vincules con bibliotecas de Rust más adelante).
rlibs Lista de módulos rust_library que deben vincularse, de forma estática, como rlibs. (Úsala con cuidado; consulta Cuando vincules con bibliotecas de Rust más adelante).
shared_libs Lista de módulos cc_library que deben vincularse, de forma dinámica, como bibliotecas compartidas.
static_libs Lista de módulos cc_library que deben vincularse, de forma estática, como bibliotecas estáticas.
whole_static_libs Lista de módulos cc_library que deben vincularse de forma estática como bibliotecas estáticas y deben incluirse por completo en la biblioteca resultante. Para las variantes rust_ffi_static, whole_static_libraries se incluirá en el archivo de biblioteca estática resultante. Para las variantes rust_library_rlib, las bibliotecas whole_static_libraries se agruparán en la biblioteca rlib resultante.

Cuando vincules con bibliotecas de Rust, te recomendamos que uses la propiedad rustlibs en lugar de rlibs o dylibs, a menos que tengas un motivo específico para hacerlo. De esta manera, el sistema de compilación puede seleccionar la vinculación correcta, según lo que requiera el módulo raíz, y se reducen las posibilidades de que un árbol de dependencias incluya las versiones rlib y dylib de una biblioteca (lo que causará que falle la compilación).

Funciones de compilación sin compatibilidad y con compatibilidad limitada

Rust de Soong ofrece compatibilidad limitada con instantáneas o imágenes de vendor y vendor_ramdisk. Sin embargo, se admiten staticlibs, cdylibs, rlibs y binaries. Para los objetivos de compilación de imágenes de proveedores, se configura la propiedad cfg de android_vndk. Puedes usarla en el código si existen diferencias entre los objetivos del sistema y los del proveedor. No se capturan rust_proc_macros como parte de las instantáneas de proveedores; si se depende de ellas, asegúrate de controlar la versión correctamente.

No se admiten imágenes de recuperación, VNDK ni productos.

Compilaciones incrementales

Los desarrolladores pueden habilitar la compilación incremental de la fuente de Rust configurando la variable de entorno SOONG_RUSTC_INCREMENTAL como true.

Advertencia: No se garantiza que se produzcan objetos binarios idénticos como los que generan los bots de compilación. Las direcciones de las funciones o los datos que se encuentran en los archivos de objeto pueden ser diferentes. Para asegurarte de que los artefactos generados sean 100% idénticos a los que compiló la infraestructura de EngProd, no configures este valor.