Esta página está destinada a los usuarios de Bazel que escriben reglas de compilación y prueba personalizadas y que desean comprender los requisitos de las reglas de Bazel en el contexto de la ejecución remota.
La ejecución remota permite que Bazel ejecute acciones en una plataforma independiente, como un centro de datos. Bazel usa un protocolo gRPC para su ejecución remota. Puedes probar la ejecución remota con bazel-buildfarm, un proyecto de código abierto que tiene como objetivo proporcionar una plataforma de ejecución remota distribuida.
En esta página, se usa la siguiente terminología cuando se hace referencia a diferentes tipos de entornos o plataformas:
- Plataforma de host: Es donde se ejecuta Bazel.
- Plataforma de ejecución: Es donde se ejecutan las acciones de Bazel.
- Plataforma de destino: Es donde se ejecutan los resultados de la compilación (y algunas acciones).
Descripción general
Cuando configures una compilación de Bazel para la ejecución remota, debes seguir los lineamientos que se describen en esta página para asegurarte de que la compilación se ejecute de forma remota sin errores. Esto se debe a la naturaleza de la ejecución remota, es decir:
Acciones de compilación aisladas. Las herramientas de compilación no conservan el estado y las dependencias no pueden filtrarse entre ellas.
Diversos entornos de ejecución. La configuración de compilación local no siempre es adecuada para los entornos de ejecución remota.
En esta página, se describen los problemas que pueden surgir cuando se implementan reglas de compilación y prueba de Bazel personalizadas para la ejecución remota, y cómo evitarlos. Abarca los siguientes temas:
- Cómo invocar herramientas de compilación a través de reglas de cadena de herramientas
- Administración de dependencias implícitas
- Administra objetos binarios que dependen de la plataforma
- Administra las reglas de WORKSPACE de configure-style
Cómo invocar herramientas de compilación a través de reglas de cadenas de herramientas
Una regla de cadena de herramientas de Bazel es un proveedor de configuración que le indica a una regla de compilación qué herramientas de compilación, como compiladores y enlazadores, usar y cómo configurarlas con los parámetros definidos por el creador de la regla. Una regla de cadena de herramientas permite que las reglas de compilación y prueba invoquen herramientas de compilación de una manera predecible y preconfigurada que sea compatible con la ejecución remota. Por ejemplo, usa una regla de cadena de herramientas en lugar de invocar herramientas de compilación a través de PATH
, JAVA_HOME
o cualquier otra variable local que no se pueda establecer en valores equivalentes (o en absoluto) en el entorno de ejecución remota.
Actualmente, existen reglas de cadena de herramientas para las reglas de compilación y prueba de Bazel para Scala, Rust y Go, y se están desarrollando nuevas reglas de cadena de herramientas para otros lenguajes y herramientas, como bash. Si no existe una regla de cadena de herramientas para la herramienta que usa tu regla, considera crear una regla de cadena de herramientas.
Administra las dependencias implícitas
Si una herramienta de compilación puede acceder a las dependencias en las acciones de compilación, esas acciones fallarán cuando se ejecuten de forma remota, ya que cada acción de compilación remota se ejecuta por separado de las demás. Algunas herramientas de compilación conservan el estado en las acciones de compilación y acceden a dependencias que no se incluyeron de forma explícita en la invocación de la herramienta, lo que provocará que fallen las acciones de compilación ejecutadas de forma remota.
Por ejemplo, cuando Bazel le indica a un compilador con estado que compile foo de forma local, el compilador conserva referencias a los resultados de la compilación de foo. Cuando Bazel le indica al compilador que compile bar, que depende de foo, sin indicar explícitamente esa dependencia en el archivo BUILD para su inclusión en la invocación del compilador, la acción se ejecuta correctamente siempre que la misma instancia del compilador se ejecute para ambas acciones (como es típico en la ejecución local). Sin embargo, dado que, en una situación de ejecución remota, cada acción de compilación ejecuta una instancia de compilador independiente, se perderán el estado del compilador y la dependencia implícita de bar en foo, y la compilación fallará.
Para ayudar a detectar y eliminar estos problemas de dependencia, Bazel 0.14.1 ofrece la zona de pruebas local de Docker, que tiene las mismas restricciones para las dependencias que la ejecución remota. Usa la zona de pruebas para preparar tu compilación para la ejecución remota. Para ello, identifica y resuelve los errores de compilación relacionados con las dependencias. Consulta Solución de problemas de la ejecución remota de Bazel con la zona de pruebas de Docker para obtener más información.
Administra objetos binarios que dependen de la plataforma
Por lo general, un objeto binario compilado en la plataforma host no se puede ejecutar de forma segura en una plataforma de ejecución remota arbitraria debido a posibles dependencias no coincidentes. Por ejemplo, el objeto binario SingleJar que se proporciona con Bazel tiene como objetivo la plataforma del host. Sin embargo, para la ejecución remota, SingleJar debe compilarse como parte del proceso de compilación de tu código para que se dirija a la plataforma de ejecución remota. (Consulta la lógica de selección de objetivos).
No envíes objetos binarios de herramientas de compilación que tu compilación requiera con tu código fuente, a menos que tengas la certeza de que se ejecutarán de forma segura en tu plataforma de ejecución. En su lugar, haz una de las siguientes acciones:
Envía o haz referencia externa al código fuente de la herramienta para que se pueda compilar para la plataforma de ejecución remota.
Preinstala la herramienta en el entorno de ejecución remota (por ejemplo, un contenedor de cadena de herramientas) si es lo suficientemente estable y usa reglas de cadena de herramientas para ejecutarla en tu compilación.
Administra las reglas WORKSPACE de configure-style
Las reglas WORKSPACE
de Bazel se pueden usar para sondear la plataforma de host en busca de herramientas y bibliotecas requeridas por la compilación, que, para las compilaciones locales, también es la plataforma de ejecución de Bazel. Si la compilación depende explícitamente de herramientas y artefactos de compilación locales, fallará durante la ejecución remota si la plataforma de ejecución remota no es idéntica a la plataforma de host.
Las siguientes acciones que realizan las reglas de WORKSPACE
no son compatibles con la ejecución remota:
Compilación de archivos binarios. La ejecución de acciones de compilación en reglas de
WORKSPACE
genera archivos binarios que son incompatibles con la plataforma de ejecución remota si es diferente de la plataforma host.Instalación de paquetes de
pip
Los paquetespip
instalados a través de reglas deWORKSPACE
requieren que sus dependencias se instalen previamente en la plataforma host. Estos paquetes, compilados específicamente para la plataforma host, serán incompatibles con la plataforma de ejecución remota si esta es diferente de la plataforma host.Creación de vínculos simbólicos a herramientas o artefactos locales. Los vínculos simbólicos a herramientas o bibliotecas instaladas en la plataforma host creados a través de reglas de
WORKSPACE
harán que la compilación falle en la plataforma de ejecución remota, ya que Bazel no podrá ubicarlos. En cambio, crea vínculos simbólicos con acciones de compilación estándares para que se pueda acceder a las herramientas y bibliotecas vinculadas simbólicamente desde el árbolrunfiles
de Bazel. No usesrepository_ctx.symlink
para crear symlinks a archivos de destino fuera del directorio del repo externo.Modifica la plataforma host. Evita crear archivos fuera del árbol
runfiles
de Bazel, crear variables de entorno y realizar acciones similares, ya que pueden comportarse de forma inesperada en la plataforma de ejecución remota.
Para ayudarte a encontrar posibles comportamientos no herméticos, puedes usar el registro de reglas del espacio de trabajo.
Si una dependencia externa ejecuta operaciones específicas que dependen de la plataforma host, debes dividir esas operaciones entre WORKSPACE
y las reglas de compilación de la siguiente manera:
Inspección de la plataforma y enumeración de dependencias. Estas operaciones se pueden ejecutar de forma segura a nivel local a través de reglas de
WORKSPACE
, que pueden verificar qué bibliotecas están instaladas, descargar paquetes que deben compilarse y preparar los artefactos necesarios para la compilación. Para la ejecución remota, estas reglas también deben admitir el uso de artefactos verificados previamente para proporcionar la información que normalmente se obtendría durante la inspección de la plataforma host. Los artefactos verificados previamente permiten que Bazel describa las dependencias como si fueran locales. Para ello, usa instrucciones condicionales o la marca--override_repository
.Genera o compila artefactos específicos del destino y mutaciones de la plataforma. Estas operaciones deben ejecutarse a través de reglas de compilación normales. Las acciones que producen artefactos específicos del objetivo para las dependencias externas deben ejecutarse durante la compilación.
Para generar más fácilmente artefactos verificados previamente para la ejecución remota, puedes usar reglas WORKSPACE
para emitir archivos generados. Puedes ejecutar esas reglas en cada entorno de ejecución nuevo, por ejemplo, dentro de cada contenedor de la cadena de herramientas, y verificar las salidas de tu compilación de ejecución remota en tu repo de código fuente para hacer referencia a ellas.
Por ejemplo, para las reglas de Tensorflow sobre cuda
y python
, las reglas de WORKSPACE
producen el siguiente BUILD files
.
Para la ejecución local, se usan los archivos que se producen al verificar el entorno del host.
Para la ejecución remota, una instrucción condicional en una variable de entorno permite que la regla use archivos que se registran en el repo.
Los archivos BUILD
declaran genrules
que pueden ejecutarse de forma local y remota, y realizar el procesamiento necesario que antes se hacía a través de repository_ctx.symlink
, como se muestra aquí.