Prácticas recomendadas

Informa un problema Ver código fuente

En esta página, se supone que estás familiarizado con Bazel y se proporcionan lineamientos y consejos sobre la estructuración de tus proyectos para aprovechar al máximo las funciones de Bazel.

Los objetivos generales son:

  • Usar dependencias detalladas para permitir el paralelismo y la incrementalidad
  • Para mantener las dependencias bien encapsuladas
  • Hacer que el código esté bien estructurado y pueda someterse a pruebas
  • Crear una configuración de compilación que sea fácil de comprender y mantener

Estos lineamientos no son requisitos: pocos proyectos podrán cumplirlos todos. Como dice la página man de lint, "Se le mostrará una recompensa especial a la primera persona para producir un programa real que no genere errores con una verificación estricta". Sin embargo, incorporar la mayor cantidad posible de estos principios debe hacer que un proyecto sea más legible, menos propenso a errores y más rápido de compilar.

En esta página, se usan los niveles de requisitos que se describen en este RFC.

Ejecuta compilaciones y pruebas

Un proyecto siempre debe poder ejecutar bazel build //... y bazel test //... correctamente en su rama estable. Los destinos que son necesarios,pero que no se compilan en determinadas circunstancias (por ejemplo, requieren marcas de compilación específicas, no se compilan en una plataforma determinada o requieren acuerdos de licencia) deben etiquetarse de la manera más específica posible (por ejemplo, “requires-osx”). Este etiquetado permite que los objetivos se filtren en un nivel más detallado que la etiqueta “manual” y permite que alguien inspeccione el archivo BUILD para comprender cuáles son las restricciones de un destino.

Y las dependencias de terceros

Puedes declarar dependencias de terceros:

  • Puedes declararlos como repositorios remotos en el archivo WORKSPACE.
  • También puedes colocarlos en un directorio llamado third_party/ debajo del directorio de tu lugar de trabajo.

Según los objetos binarios

Todo debe compilarse desde la fuente siempre que sea posible. Por lo general, esto significa que, en lugar de depender de una biblioteca some-library.so, debes crear un archivo BUILD y compilar some-library.so a partir de sus fuentes y, luego, depender de ese destino.

La compilación siempre desde la fuente garantiza que una compilación no use una biblioteca compilada con marcas incompatibles o una arquitectura diferente. También hay algunas funciones, como la cobertura, el análisis estático o el análisis dinámico, que solo funcionan en la fuente.

Control de versiones

Siempre que sea posible, prefiera compilar todo el código desde la cabeza. Cuando se deban usar versiones, evita incluir la versión en el nombre de destino (por ejemplo, //guava, no //guava-20.0). Esta denominación facilita la actualización de la biblioteca (solo se debe actualizar un destino). También es más resistente a los problemas de dependencia de diamantes: si una biblioteca depende de guava-19.0 y otra depende de guava-20.0, podrías terminar con una biblioteca que intente depender de dos versiones diferentes. Si creaste un alias engañoso para apuntar ambos destinos a una biblioteca guava, los archivos BUILD son engañosos.

Usa el archivo .bazelrc

Para obtener opciones específicas del proyecto, usa el archivo de configuración de tu workspace/.bazelrc (consulta el formato bazelrc).

Si deseas admitir opciones por usuario para tu proyecto que no quieres registrar en el control de código fuente, incluye la siguiente línea:

try-import %workspace%/user.bazelrc

(o cualquier otro nombre de archivo) en tu workspace/.bazelrc y agrega user.bazelrc a tu .gitignore.

Paquetes

Todos los directorios que contienen archivos que se pueden compilar deben ser un paquete. Si un archivo BUILD hace referencia a archivos en subdirectorios (como srcs = ["a/b/C.java"]), es una señal de que se debe agregar un archivo BUILD a ese subdirectorio. Mientras más larga sea esta estructura, más probable será que se creen dependencias circulares de forma involuntaria, el alcance de un objetivo se desplazará y una cantidad creciente de dependencias inversas deberá actualizarse.