Hermeticidad

En esta página, se describe la hermeticidad, los beneficios de usar compilaciones herméticas y las estrategias para identificar comportamientos no herméticos en las compilaciones.

Descripción general

Cuando se le proporciona el mismo código fuente de entrada y la misma configuración del producto, un sistema de compilación hermético siempre muestra el mismo resultado aislando la compilación de los cambios en el sistema host.

Para aislar la compilación, las compilaciones herméticas no son sensibles a las bibliotecas y otro software instalado en la máquina anfitrión local o remota. Dependen de versiones específicas de las herramientas de compilación, como los compiladores, y de las dependencias, como las bibliotecas. Esto hace que el proceso de compilación sea independiente, ya que no depende de servicios externos al entorno de compilación.

Los dos aspectos importantes de la hermeticidad son los siguientes:

  • Aislamiento: Los sistemas de compilación herméticos tratan las herramientas como código fuente. Descargan copias de las herramientas, administran su almacenamiento y las usan dentro de árboles de archivos administrados. Esto crea aislamiento entre la máquina anfitrión y el usuario local, incluidas las versiones instaladas de idiomas.
  • Identidad de la fuente: Los sistemas de compilación herméticos intentan garantizar la igualdad de las entradas. Los repositorios de código, como Git, identifican conjuntos de mutaciones de código con un código hash único. Los sistemas de compilación herméticos usan este hash para identificar cambios en la entrada de la compilación.

Beneficios

Los beneficios principales de las compilaciones herméticas son los siguientes:

  • Velocidad: El resultado de una acción se puede almacenar en caché y no es necesario volver a ejecutar la acción, a menos que cambien las entradas.
  • Ejecución paralela: Para entradas y salidas determinadas, el sistema de compilación puede construir un grafo de todas las acciones a fin de calcular una ejecución paralela y eficiente. El sistema de compilación carga las reglas y calcula un gráfico de acción y entradas de hash para buscar en la caché.
  • Varias compilaciones: Puedes compilar varias compilaciones herméticas en la misma máquina, cada una con herramientas y versiones diferentes.
  • Reproducibilidad: Las compilaciones herméticas son útiles para solucionar problemas porque conoces las condiciones exactas que produjeron la compilación.

Cómo identificar la no hermeticidad

Si te preparas para cambiar a Bazel, la migración es más fácil si mejoras la hermeticidad de las compilaciones existentes con anticipación. Algunas fuentes comunes de no hermeticidad en las compilaciones son las siguientes:

  • Procesamiento arbitrario en archivos .mk
  • Acciones o herramientas que crean archivos de manera no determinista, por lo general, incluyen IDs de compilación o marcas de tiempo
  • Objetos binarios del sistema que difieren entre hosts (como objetos binarios /usr/bin, rutas de acceso absolutas y compiladores de C++ para la configuración automática de reglas nativas de C++)
  • Escribir en el árbol de fuentes durante la compilación Esto evita que el mismo árbol de fuentes se use para otro destino. La primera compilación escribe en el árbol de fuentes, lo que corrige el árbol de fuentes del destino A. Entonces, tratar de crear el objetivo B puede fallar.

Soluciona problemas de compilaciones no herméticas

A partir de la ejecución local, los problemas que afectan los aciertos de caché local revelan acciones no herméticas.

  • Asegúrate de que las compilaciones secuenciales nulas sean nulas: si ejecutas make y la compilación se realiza correctamente, volver a ejecutar la compilación no debería volver a compilar ningún destino. Si ejecutas cada paso de la compilación dos veces o en sistemas diferentes, comparas un hash del contenido del archivo y obtienes resultados que difieren, la compilación no es reproducible.
  • Ejecuta los pasos para depurar los aciertos de caché local de una variedad de máquinas cliente potenciales y asegurarte de detectar cualquier caso en el que el entorno del cliente se filtre en las acciones.
  • Ejecuta una compilación dentro de un contenedor de Docker que solo contenga el árbol de fuentes verificado y una lista explícita de herramientas de host. Las fallas de compilación y los mensajes de error detectarán dependencias implícitas del sistema.
  • Descubre y corrige problemas de hermeticidad con reglas de ejecución remota.
  • Habilita una zona de pruebas estricta a nivel por acción, ya que las acciones de una compilación pueden tener estado y afectar la compilación o el resultado.
  • Las reglas del lugar de trabajo permiten a los desarrolladores agregar dependencias a lugares de trabajo externos, pero son lo suficientemente enriquecidas como para permitir que ocurra un procesamiento arbitrario en el proceso. Puedes obtener un registro de algunas acciones potencialmente no herméticas en las reglas del lugar de trabajo de Bazel si agregas la marca --experimental_workspace_rules_log_file=PATH al comando de Bazel.

Hermeticidad con Bazel

Para obtener más información sobre cómo tuvieron éxito otros proyectos mediante compilaciones herméticas con Bazel, consulta estas charlas de BazelCon: