Reglas de escritura en Windows

Informar un problema . Ver fuente . . Por la noche · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Esta página se enfoca en la escritura de reglas compatibles con Windows, problemas comunes de la escritura de reglas portátiles y algunas soluciones.

Rutas de acceso

Problemas:

  • Límite de longitud: La longitud máxima de la ruta de interacciones es de 259 caracteres.

    Aunque Windows también admite rutas de acceso más largas (de hasta 32,767 caracteres), muchos programas se compilan con el límite inferior.

    Ten esto en cuenta sobre los programas que ejecutas en las acciones.

  • Directorio de trabajo: También tiene un límite de 259 caracteres.

    Los procesos no pueden cd a un directorio de más de 259 caracteres.

  • Distinción entre mayúsculas y minúsculas: Las rutas de acceso de Windows no distinguen mayúsculas de minúsculas, y las de Unix no distinguen mayúsculas de minúsculas.

    Ten esto en cuenta cuando crees líneas de comandos para acciones.

  • Separadores de ruta de acceso: son barras inversas (\`), not forward slash (/`).

    Bazel almacena rutas de acceso de estilo Unix con separadores /. Aunque algunos programas de Windows admiten Las rutas de acceso de estilo Unix, otras no. Algunos comandos integrados en cmd.exe los admiten, otros no.

    Es mejor usar siempre \` separators on Windows: replace/with` cuando creas el comando de código abierto y variables de entorno para acciones.

  • Rutas de acceso absolutas: no deben comenzar con una barra (/).

    Las rutas de acceso absolutas en Windows comienzan con una letra de unidad, como C:\foo\bar.txt. No hay una sola raíz del sistema de archivos.

    Ten en cuenta esto si tu regla verifica si una ruta de acceso es absoluta. Rutas de acceso absolutas deberían evitarse ya que a menudo no son portátiles.

Soluciones:

  • Usa rutas de acceso cortas.

    Evita los nombres de directorios largos, las estructuras de directorios profundamente anidadas, los nombres de archivos largos y los espacios de trabajo extensos. y nombres de objetivos largos.

    Todas estas pueden convertirse en componentes de la ruta de acceso de las acciones archivos de entrada y es posible que agote la longitud de la ruta de acceso límite.

  • Usa una raíz de salida corta.

    Usa la marca --output_user_root=<path> para especificar una ruta corta para los resultados de Bazel. Una buena idea es tener una unidad (o unidad virtual) solo para los resultados de Bazel (como el archivo D:\`), and adding this line to your.bazelrc):

    build --output_user_root=D:/
    

    o

    build --output_user_root=C:/_bzl
    
  • Usa uniones.

    En pocas palabras,[1] las uniones son symlinks de directorios. Las uniones son fáciles de crear y pueden apuntar a directorios (en la misma computadora) con rutas de acceso largas. Si una acción de compilación crea una intersección cuya ruta de acceso es corta pero cuyo destino es largo, entonces las herramientas con límite de ruta de acceso corta pueden acceder los archivos en el directorio de la unión.

    En archivos .bat o en cmd.exe, puedes crear uniones como las siguientes:

    mklink /J c:\path\to\junction c:\path\to\very\long\target\path
    

    [1]: En sentido estricto Las uniones no son vínculos simbólicos, pero las acciones de compilación pueden considerar a las uniones como vínculos simbólicos del directorio.

  • Reemplaza / por `` en rutas de acceso en actions / envvars.

    Cuando crees la línea de comandos o las variables de entorno para una acción, haz que las rutas al estilo de Windows. Ejemplo:

    def as_path(p, is_windows):
        if is_windows:
            return p.replace("/", "\\")
        else:
            return p
    

Variables de entorno

Problemas:

  • Distinción entre mayúsculas y minúsculas: Los nombres de las variables de entorno de Windows no distinguen mayúsculas de minúsculas.

    Por ejemplo, en Java, System.getenv("SystemRoot") y System.getenv("SYSTEMROOT") arroja lo siguiente: mismo resultado. (Esto también se aplica a otros idiomas).

  • Hermeticity: Las acciones deben usar la menor cantidad posible de variables de entorno personalizadas.

    Las variables de entorno son parte de la clave de caché de la acción. Si una acción usa variables de entorno que cambian con frecuencia o se personalizan para los usuarios, lo que hace que la regla tenga menos almacenamiento en caché.

Soluciones:

  • Usa solo nombres de variables de entorno en mayúsculas.

    Esta opción funciona en Windows, macOS y Linux.

  • Minimiza los entornos de acción.

    Cuando uses ctx.actions.run, establece el entorno en ctx.configuration.default_shell_env. Si el botón necesita más variables de entorno, colócalas todas en un diccionario y pásalas a la acción. Ejemplo:

    load("@bazel_skylib//lib:dicts.bzl", "dicts")
    
    def _make_env(ctx, output_file, is_windows):
        out_path = output_file.path
        if is_windows:
            out_path = out_path.replace("/", "\\")
        return dicts.add(ctx.configuration.default_shell_env, {"MY_OUTPUT": out_path})
    

Acciones

Problemas:

  • Salidas ejecutables: Cada archivo ejecutable debe tener una extensión ejecutable.

    Las extensiones más comunes son .exe (archivos binarios) y .bat (secuencias de comandos por lotes).

    Ten en cuenta que las secuencias de comandos de shell (.sh) NO son ejecutables en Windows. no puedes especificarlas como executable de ctx.actions.run. Tampoco hay un permiso +x para que los archivos puedan tener, por lo que no puede ejecutar archivos arbitrarios como en Linux.

  • Comandos de Bash: Para lograr la portabilidad, evita ejecutar comandos Bash directamente en acciones.

    Bash es muy popular en sistemas similares a Unix, pero a menudo no está disponible en Windows. Bazel es depende cada vez menos de Bash (MSYS2), por lo que, en el futuro, es menos probable que los usuarios tengan MSYS2. junto con Bazel. Para que las reglas sean más fáciles de usar en Windows, evita ejecutar comandos Bash en acciones.

  • Terminaciones de línea: Windows usa CRLF (\r\n); los sistemas similares a Unix usan LF (\n).

    Ten esto en cuenta cuando compares archivos de texto. Ten en cuenta la configuración de Git, en especial, finales al momento de pagar o confirmar. (Consulta la configuración de core.autocrlf de Git).

Soluciones:

  • Usa una regla hecha a propósito sin Bash.

    native.genrule() es un wrapper para comandos de Bash y, a menudo, se usa para resolver problemas simples. como copiar un archivo o escribir un archivo de texto. Puedes evitar confiar en Bash (y reinventar la wheel): Consulta si bazel-skylib tiene una regla específica para tus necesidades. Ninguno de ellos depende de Bash cuando se compila o prueba en Windows.

    Ejemplos de reglas de compilación:

    • copy_file() (fuente, documentación): copia un archivo en otro lugar y, opcionalmente, lo hace ejecutable

    • write_file() (fuente, documentación): escribe un archivo de texto con las terminaciones de línea deseadas (auto, unix o windows); opcionalmente, lo que lo hace ejecutable (si es una secuencia de comandos)

    • run_binary() (fuente, documentación): Ejecuta un objeto binario (o una regla *_binary) con entradas determinadas y salidas esperadas como una acción de compilación. (este es un wrapper de reglas de compilación para ctx.actions.run)

    • native_binary() (fuente, documentación): une un objeto binario nativo en una regla *_binary, que puedes usar en bazel run o usar en run_binary() Atributo tool o atributo tools de native.genrule()

    Ejemplos de reglas de prueba:

  • En Windows, considera usar secuencias de comandos .bat para cuestiones triviales.

    En lugar de secuencias de comandos .sh, puedes resolver tareas triviales con secuencias de comandos .bat.

    Por ejemplo, si necesitas una secuencia de comandos que no realiza ninguna acción, que imprima un mensaje o que salga con una configuración código de error, será suficiente con un archivo .bat simple. Si tu regla devuelve un DefaultInfo() , el campo executable puede hacer referencia a ese archivo .bat en Windows.

    Además, como las extensiones de archivo no son importantes en macOS ni Linux, siempre puedes usar .bat como incluso para secuencias de comandos de shell.

    Ten en cuenta que no se pueden ejecutar archivos .bat vacíos. Si necesitas una secuencia de comandos vacía, escribe un espacio. que haya en él.

  • Usa Bash de acuerdo con principios.

    En las reglas de compilación y prueba de Starlark, usa ctx.actions.run_shell para ejecutar secuencias de comandos de Bash y Bash comandos como acciones.

    En las macros de Starlark, une las secuencias de comandos y los comandos de Bash en una native.sh_binary() o native.genrule() Bazel verificará si Bash está disponible y ejecutará la secuencia de comandos o el comando mediante Bash.

    En las reglas del repositorio de Starlark, intenta evitar Bash por completo. Por el momento, Bazel no ofrece formas de ejecutar Comandos Bash de acuerdo con las reglas del repositorio

Borra archivos

Problemas:

  • No puedes borrar archivos mientras estás abierto.

    No se pueden borrar los archivos abiertos (de forma predeterminada); los intentos dan como resultado “Acceso denegado” errores. Si no puedes borrar un archivo, es posible que un proceso en ejecución lo retenga abiertos.

  • No se puede borrar el directorio de trabajo de un proceso en ejecución.

    Los procesos tienen un controlador abierto para su directorio de trabajo y el directorio no se puede borrar. hasta que el proceso finalice.

Soluciones:

  • En el código, intenta cerrar los archivos con anticipación.

    En Java, usa try-with-resources. En Python, usa with open(...) as f:. En principio, intentar cerrar los identificadores lo antes posible.