Es una especificación exhaustiva del entorno de ejecución de la prueba.
Fondo
El lenguaje BUILD de Bazel incluye reglas que se pueden usar para definir programas de prueba automatizados en muchos lenguajes.
Las pruebas se ejecutan con bazel test
.
Los usuarios también pueden ejecutar archivos binarios de prueba directamente. Esto se permite, pero no se recomienda, ya que esa invocación no cumplirá con los mandatos que se describen a continuación.
Las pruebas deben ser herméticas, es decir, solo deben acceder a los recursos de los que tienen una dependencia declarada. Si las pruebas no son herméticas, no arrojan resultados reproducibles históricamente. Esto podría ser un problema significativo para la identificación de culpables (determinar qué cambio interrumpió una prueba), la auditabilidad de la ingeniería de versiones y el aislamiento de recursos de las pruebas (los frameworks de pruebas automatizadas no deberían realizar un ataque DDoS a un servidor porque algunas pruebas se comunican con él).
Objetivo
El objetivo de esta página es establecer formalmente el entorno de ejecución y el comportamiento esperado de las pruebas de Bazel. También impondrá requisitos en el ejecutor de pruebas y el sistema de compilación.
La especificación del entorno de prueba ayuda a los autores de pruebas a evitar depender de un comportamiento no especificado y, por lo tanto, le da a la infraestructura de pruebas más libertad para realizar cambios en la implementación. La especificación ajusta algunos agujeros que actualmente permiten que muchas pruebas pasen a pesar de no ser herméticas, determinísticas y reentrantes de forma adecuada.
El objetivo de esta página es ser tanto normativa como autorizada. Si esta especificación y el comportamiento implementado del ejecutor de pruebas no coinciden, la especificación tiene prioridad.
Especificación propuesta
Las palabras clave “DEBE”, “NO DEBE”, “OBLIGATORIO”, “DEBERÁ”, “NO DEBERÁ”, “DEBERÍA”, “NO DEBERÍA”, “RECOMENDADO”, “PUEDE” y “OPCIONAL” se deben interpretar como se describe en el RFC 2119 del IETF.
Propósito de las pruebas
El propósito de las pruebas de Bazel es confirmar alguna propiedad de los archivos fuente que se registraron en el repositorio. (En esta página, "archivos fuente" incluye datos de prueba, resultados de referencia y cualquier otro elemento que se mantenga bajo control de versión). Un usuario escribe una prueba para confirmar una invariante que espera que se mantenga. Otros usuarios ejecutan la prueba más adelante para verificar si se incumplió la invariante. Si la prueba depende de alguna variable que no sean archivos fuente (no hermética), su valor disminuye, ya que los usuarios posteriores no pueden tener la certeza de que sus cambios son los culpables cuando la prueba deja de pasar.
Por lo tanto, el resultado de una prueba solo debe depender de lo siguiente:
- Archivos fuente de los que la prueba tiene una dependencia declarada
- productos del sistema de compilación en los que la prueba tiene una dependencia declarada
- Recursos cuyo comportamiento garantiza el ejecutor de pruebas que permanecerá constante
Actualmente, no se aplica este comportamiento. Sin embargo, los ejecutores de pruebas se reservan el derecho de agregar dicha aplicación en el futuro.
Función del sistema de compilación
Las reglas de prueba son análogas a las reglas binarias, ya que cada una debe generar un programa ejecutable. En algunos lenguajes, este es un programa auxiliar que combina un arnés específico del lenguaje con el código de prueba. Las reglas de prueba también deben producir otros resultados. Además del ejecutable de prueba principal, el ejecutor de pruebas necesitará un manifiesto de runfiles, archivos de entrada que deben estar disponibles para la prueba en el tiempo de ejecución, y es posible que necesite información sobre el tipo, el tamaño y las etiquetas de una prueba.
El sistema de compilación puede usar los runfiles para entregar código y datos. (Esto se puede usar como una optimización para reducir el tamaño de cada archivo binario de prueba compartiendo archivos entre pruebas, por ejemplo, a través de la vinculación dinámica). El sistema de compilación debe garantizar que el ejecutable generado cargue estos archivos a través de la imagen de archivos ejecutables proporcionada por el ejecutor de pruebas, en lugar de referencias codificadas de forma rígida a ubicaciones absolutas en el árbol de origen o de salida.
Función del ejecutor de pruebas
Desde el punto de vista del ejecutor de pruebas, cada prueba es un programa que se puede invocar con execve()
. Puede haber otras formas de ejecutar pruebas. Por ejemplo, un IDE podría permitir la ejecución de pruebas de Java en el proceso. Sin embargo, el resultado de ejecutar la prueba como un proceso independiente debe considerarse definitivo. Si un proceso de prueba se ejecuta hasta completarse y finaliza con normalidad con un código de salida cero, la prueba se aprobó. Cualquier otro resultado se considera un error de prueba. En particular, escribir cualquiera de las cadenas PASS
o FAIL
en stdout no tiene importancia para el ejecutor de pruebas.
Si una prueba tarda demasiado en ejecutarse, supera algún límite de recursos o el ejecutor de pruebas detecta un comportamiento prohibido, puede optar por detener la prueba y tratar la ejecución como un error. El ejecutor no debe informar que la prueba se aprobó después de enviar un indicador al proceso de prueba o a cualquiera de sus procesos secundarios.
Todo el destino de la prueba (no los métodos o las pruebas individuales) tiene una cantidad limitada de tiempo para completarse. El límite de tiempo para una prueba se basa en su atributo timeout
, según la siguiente tabla:
tiempo de espera agotado | Límite de tiempo (s) |
---|---|
short | 60 |
Moderada | 300 |
long | 900 |
eterno | 3600 |
Las pruebas que no especifican un tiempo de espera de forma explícita tienen uno implícito según el size
de la prueba, de la siguiente manera:
tamaño | Etiqueta de tiempo de espera implícito |
---|---|
pequeña | short |
media | Moderada |
grande | long |
enorme | eterno |
A una prueba "grande" sin un parámetro de configuración de tiempo de espera explícito se le asignarán 900 segundos para ejecutarse. Una prueba "media" con un tiempo de espera "corto" tendrá asignados 60 segundos.
A diferencia de timeout
, size
también determina el uso máximo supuesto de otros recursos (como la RAM) cuando se ejecuta la prueba de forma local, como se describe en Definiciones comunes.
Todas las combinaciones de etiquetas size
y timeout
son válidas, por lo que se puede declarar que una prueba "enorme" tiene un tiempo de espera "corto". Presumiblemente, haría cosas horribles muy rápido.
Las pruebas pueden devolver resultados de forma arbitrariamente rápida, independientemente del tiempo de espera. Una prueba no se penaliza por un tiempo de espera demasiado generoso, aunque se puede emitir una advertencia: En general, debes establecer el tiempo de espera lo más ajustado posible sin incurrir en inestabilidad.
El tiempo de espera de la prueba se puede anular con la marca --test_timeout
de Bazel cuando se ejecuta manualmente en condiciones que se sabe que son lentas. Los valores de --test_timeout
están en segundos. Por ejemplo, --test_timeout=120
establece el tiempo de espera de la prueba en dos minutos.
También se recomienda un límite inferior para los tiempos de espera de las pruebas, como se indica a continuación:
tiempo de espera agotado | Tiempo mínimo (s) |
---|---|
short | 0 |
Moderada | 30 |
long | 300 |
eterno | 900 |
Por ejemplo, si una prueba "moderada" se completa en 5.5 s, considera establecer timeout =
"short"
o size = "small"
. Si usas la opción de línea de comandos --test_verbose_timeout_warnings
de bazel, se mostrarán las pruebas cuyo tamaño especificado sea demasiado grande.
Los tamaños y los tiempos de espera de las pruebas se especifican en el archivo BUILD según la especificación aquí. Si no se especifica, el tamaño de una prueba se establecerá de forma predeterminada en "mediano".
Si el proceso principal de una prueba finaliza, pero algunos de sus procesos secundarios siguen en ejecución, el ejecutor de pruebas debe considerar que la ejecución se completó y contarla como un éxito o un error según el código de salida observado del proceso principal. El ejecutor de pruebas puede finalizar cualquier proceso no deseado. Las pruebas no deberían filtrar procesos de esta manera.
Fragmentación de pruebas
Las pruebas se pueden paralelizar a través de la fragmentación de pruebas. Consulta --test_sharding_strategy
y shard_count
para habilitar la fragmentación de pruebas. Cuando la fragmentación está habilitada, el ejecutor de pruebas se inicia una vez por fragmento. La variable de entorno TEST_TOTAL_SHARDS
es la cantidad de fragmentos, y TEST_SHARD_INDEX
es el índice del fragmento, que comienza en 0. Los ejecutores usan esta información para seleccionar qué pruebas ejecutar, por ejemplo, con una estrategia de turnos. No todos los ejecutores de pruebas admiten la fragmentación. Si un ejecutor admite el sharding, debe crear o actualizar la fecha de última modificación del archivo especificado por TEST_SHARD_STATUS_FILE
. De lo contrario, si --incompatible_check_sharding_support
está habilitado, Bazel fallará la prueba si está fragmentada.
Condiciones iniciales
Cuando se ejecuta una prueba, el ejecutor de pruebas debe establecer ciertas condiciones iniciales.
El ejecutor de pruebas debe invocar cada prueba con la ruta de acceso al ejecutable de prueba en argv[0]
. Esta ruta de acceso debe ser relativa y estar debajo del directorio actual de la prueba (que se encuentra en el árbol de runfiles, consulta a continuación). El ejecutor de pruebas no debe pasar ningún otro argumento a una prueba, a menos que el usuario lo solicite explícitamente.
El bloque de entorno inicial se compondrá de la siguiente manera:
Variable | Valor | Estado |
---|---|---|
HOME |
valor de $TEST_TMPDIR |
recomendado |
LANG |
unset | obligatorio |
LANGUAGE |
unset | obligatorio |
LC_ALL |
unset | obligatorio |
LC_COLLATE |
unset | obligatorio |
LC_CTYPE |
unset | obligatorio |
LC_MESSAGES |
unset | obligatorio |
LC_MONETARY |
unset | obligatorio |
LC_NUMERIC |
unset | obligatorio |
LC_TIME |
unset | obligatorio |
LD_LIBRARY_PATH |
Lista de directorios separados por dos puntos que contienen bibliotecas compartidas | opcional |
JAVA_RUNFILES |
valor de $TEST_SRCDIR |
obsoleto |
LOGNAME |
valor de $USER |
obligatorio |
PATH |
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:. |
recomendado |
PWD |
$TEST_SRCDIR/workspace-name |
recomendado |
SHLVL |
2 |
recomendado |
TEST_INFRASTRUCTURE_FAILURE_FILE |
Ruta de acceso absoluta a un archivo privado en un directorio grabable (este archivo solo se debe usar para informar fallas que se originan en la infraestructura de pruebas, no como un mecanismo general para informar fallas no determinísticas de las pruebas. En este contexto, la infraestructura de pruebas se define como los sistemas o las bibliotecas que no son específicos de las pruebas, pero que pueden causar fallas en las pruebas debido a un mal funcionamiento. La primera línea es el nombre del componente de infraestructura de pruebas que causó la falla, y la segunda es una descripción legible de la falla. Se ignoran las líneas adicionales). | opcional |
TEST_LOGSPLITTER_OUTPUT_FILE |
Ruta de acceso absoluta a un archivo privado en un directorio grabable (se usa para escribir el registro de Logsplitter en formato de búfer de protocolo) | opcional |
TEST_PREMATURE_EXIT_FILE |
Ruta de acceso absoluta a un archivo privado en un directorio grabable (se usa para detectar llamadas a exit() ) |
opcional |
TEST_RANDOM_SEED |
Si se usa la opción --runs_per_test , TEST_RANDOM_SEED se establece en run number (a partir de 1) para cada ejecución de prueba individual. |
opcional |
TEST_RUN_NUMBER |
Si se usa la opción --runs_per_test , TEST_RUN_NUMBER se establece en run number (a partir de 1) para cada ejecución de prueba individual. |
opcional |
TEST_TARGET |
El nombre del destino que se está probando | opcional |
TEST_SIZE |
La prueba size |
opcional |
TEST_TIMEOUT |
La prueba timeout en segundos |
opcional |
TEST_SHARD_INDEX |
Índice de fragmento, si se usa sharding |
opcional |
TEST_SHARD_STATUS_FILE |
ruta de acceso al archivo que se debe tocar para indicar la compatibilidad con sharding |
opcional |
TEST_SRCDIR |
Ruta de acceso absoluta a la base del árbol de archivos de ejecución | obligatorio |
TEST_TOTAL_SHARDS |
total
shard count ,
si se usa sharding |
opcional |
TEST_TMPDIR |
Ruta de acceso absoluta a un directorio privado con permisos de escritura | obligatorio |
TEST_WORKSPACE |
El nombre del espacio de trabajo del repositorio local | opcional |
TEST_UNDECLARED_OUTPUTS_DIR |
Ruta de acceso absoluta a un directorio privado con permiso de escritura (se usa para escribir resultados de pruebas no declarados). Todos los archivos escritos en el directorio TEST_UNDECLARED_OUTPUTS_DIR se comprimirán y se agregarán a un archivo outputs.zip en bazel-testlogs . |
opcional |
TEST_UNDECLARED_OUTPUTS_ANNOTATIONS_DIR |
Ruta de acceso absoluta a un directorio privado con permisos de escritura (se usa para escribir archivos de anotación de salida de prueba no declarados .part y .pb ). |
opcional |
TEST_WARNINGS_OUTPUT_FILE |
Ruta de acceso absoluta a un archivo privado en un directorio con permisos de escritura (se usa para escribir advertencias sobre el destino de la prueba) | opcional |
TESTBRIDGE_TEST_ONLY |
valor de --test_filter , si se especifica |
opcional |
TZ |
UTC |
obligatorio |
USER |
valor de getpwuid(getuid())->pw_name |
obligatorio |
XML_OUTPUT_FILE |
Ubicación en la que las acciones de prueba deben escribir un archivo de salida XML de resultados de pruebas. De lo contrario, Bazel genera un archivo de salida XML predeterminado que incluye el registro de la prueba como parte de la acción de prueba. El esquema XML se basa en el esquema de resultados de pruebas de JUnit. | opcional |
BAZEL_TEST |
Indica que bazel test está ejecutando el archivo ejecutable de prueba. |
obligatorio |
El entorno puede contener entradas adicionales. Las pruebas no deben depender de la presencia, la ausencia o el valor de ninguna variable de entorno que no se haya mencionado anteriormente.
El directorio de trabajo inicial será $TEST_SRCDIR/$TEST_WORKSPACE
.
El ID del proceso actual, el ID del grupo de procesos, el ID de sesión y el ID del proceso principal no están especificados. El proceso puede ser o no un líder de grupo de procesos o un líder de sesión. El proceso puede tener o no una terminal de control. El proceso puede tener cero o más procesos secundarios en ejecución o sin recopilar. El proceso no debe tener varios subprocesos cuando el código de prueba toma el control.
El descriptor de archivo 0 (stdin
) debe estar abierto para lectura, pero no se especifica a qué está adjunto. Las pruebas no deben leer desde él. Los descriptores de archivos 1 (stdout
) y 2 (stderr
) deben estar abiertos para escritura, pero no se especifica a qué están adjuntos. Puede ser una terminal, una canalización, un archivo normal o cualquier otro elemento en el que se puedan escribir caracteres. Pueden compartir una entrada en la tabla de archivos abiertos (lo que significa que no pueden buscar de forma independiente). Las pruebas no deben heredar ningún otro descriptor de archivo abierto.
La umask inicial debe ser 022
o 027
.
No debe haber alarmas ni temporizadores de intervalo pendientes.
La máscara inicial de los indicadores bloqueados debe estar vacía. Todos los indicadores se establecerán en su acción predeterminada.
Los límites iniciales de recursos, tanto flexibles como estrictos, deben establecerse de la siguiente manera:
Recurso | Límite |
---|---|
RLIMIT_AS |
unlimited |
RLIMIT_CORE |
sin especificar |
RLIMIT_CPU |
unlimited |
RLIMIT_DATA |
unlimited |
RLIMIT_FSIZE |
unlimited |
RLIMIT_LOCKS |
unlimited |
RLIMIT_MEMLOCK |
unlimited |
RLIMIT_MSGQUEUE |
sin especificar |
RLIMIT_NICE |
sin especificar |
RLIMIT_NOFILE |
al menos 1,024 |
RLIMIT_NPROC |
sin especificar |
RLIMIT_RSS |
unlimited |
RLIMIT_RTPRIO |
sin especificar |
RLIMIT_SIGPENDING |
sin especificar |
RLIMIT_STACK |
ilimitado o 2044 KB <= rlim <= 8192 KB |
Los tiempos de proceso iniciales (como los que devuelve times()
) y la utilización de recursos (como los que devuelve getrusage()
) no se especifican.
No se especifican la política de programación ni la prioridad iniciales.
Rol del sistema host
Además de los aspectos del contexto del usuario que controla directamente el ejecutor de pruebas, el sistema operativo en el que se ejecutan las pruebas debe satisfacer ciertas propiedades para que una ejecución de prueba sea válida.
Sistema de archivos
El directorio raíz que observa una prueba puede ser o no el directorio raíz real.
Se debe instalar /proc
.
Todas las herramientas de compilación deben estar presentes en las rutas de acceso absolutas en /usr
que utiliza una instalación local.
Es posible que las rutas que comienzan con /home
no estén disponibles. Las pruebas no deben acceder a ninguna de esas rutas.
/tmp
debe ser grabable, pero las pruebas deben evitar usar estas rutas.
Las pruebas no deben suponer que hay una ruta constante disponible para su uso exclusivo.
Las pruebas no deben suponer que los atimes están habilitados para ningún sistema de archivos activado.
Usuarios y grupos
Deben existir los usuarios root, nobody y unittest. Deben existir los grupos raíz, nobody y eng.
Las pruebas se deben ejecutar como un usuario no raíz. Los IDs de usuario reales y efectivos deben ser iguales, al igual que los IDs de grupo. Además de esto, no se especifican el ID de usuario actual, el ID de grupo, el nombre de usuario ni el nombre de grupo. No se especifica el conjunto de IDs de grupo complementarios.
El ID de usuario y el ID de grupo actuales deben tener nombres correspondientes que se puedan recuperar con getpwuid()
y getgrgid()
. Es posible que no ocurra lo mismo con los IDs de grupo complementarios.
El usuario actual debe tener un directorio principal. Es posible que no se pueda escribir en él. Las pruebas no deben intentar escribir en él.
Redes
El nombre de host no está especificado. Puede contener un punto o no. La resolución del nombre de host debe proporcionar una dirección IP del host actual. La resolución del corte del nombre de host después del primer punto también debe funcionar. El nombre de host localhost debe resolverse.
Otros recursos
A las pruebas se les otorga al menos un núcleo de CPU. Es posible que haya otros disponibles, pero no se garantiza. No se especifican otros aspectos del rendimiento de este núcleo. Puedes aumentar la reserva a una mayor cantidad de núcleos de CPU agregando la etiqueta "cpu:n" (donde n es un número positivo) a una regla de prueba. Si una máquina tiene menos núcleos de CPU totales de los solicitados, Bazel igual ejecutará la prueba. Si una prueba usa fragmentación, cada fragmento individual reservará la cantidad de núcleos de CPU especificada aquí.
Las pruebas pueden crear subprocesos, pero no grupos de procesos ni sesiones.
Existe un límite en la cantidad de archivos de entrada que puede consumir una prueba. Este límite está sujeto a cambios, pero actualmente se encuentra en el rango de decenas de miles de entradas.
Hora y fecha
No se especifican la fecha y la hora actuales. No se especificó la zona horaria del sistema.
Es posible que X Windows esté disponible o no. Las pruebas que necesitan un servidor X deben iniciar Xvfb.
Prueba la interacción con el sistema de archivos
Todas las rutas de acceso a archivos especificadas en las variables de entorno de prueba apuntan a algún lugar del sistema de archivos local, a menos que se especifique lo contrario.
Las pruebas solo deben crear archivos dentro de los directorios especificados por $TEST_TMPDIR
y $TEST_UNDECLARED_OUTPUTS_DIR
(si se establecen).
Estos directorios estarán vacíos inicialmente.
Las pruebas no deben intentar quitar, cambiar los permisos con chmod ni alterar estos directorios de ninguna otra manera.
Es posible que estos directorios sean vínculos simbólicos.
El tipo de sistema de archivos de $TEST_TMPDIR/.
permanece sin especificar.
Las pruebas también pueden escribir archivos .part en $TEST_UNDECLARED_OUTPUTS_ANNOTATIONS_DIR
para anotar archivos de salida no declarados.
En casos excepcionales, es posible que una prueba se vea obligada a crear archivos en /tmp
. Por ejemplo, los límites de longitud de ruta para los sockets de dominio Unix suelen requerir la creación del socket en /tmp
. Bazel no podrá hacer un seguimiento de esos archivos. La prueba en sí debe encargarse de ser hermética, de usar rutas únicas para evitar conflictos con otras pruebas y procesos que no sean de prueba que se ejecuten de forma simultánea, y de limpiar los archivos que crea en /tmp
.
Algunos frameworks de prueba populares, como JUnit4 TemporaryFolder
o Go TempDir
, tienen sus propias formas de crear un directorio temporal en /tmp
. Estos frameworks de pruebas incluyen funciones que limpian los archivos en /tmp
, por lo que puedes usarlos aunque creen archivos fuera de TEST_TMPDIR
.
Las pruebas deben acceder a las entradas a través del mecanismo de runfiles o de otras partes del entorno de ejecución que estén específicamente diseñadas para que los archivos de entrada estén disponibles.
Las pruebas no deben acceder a otros resultados del sistema de compilación en rutas de acceso inferidas a partir de la ubicación de su propio ejecutable.
No se especifica si el árbol de archivos ejecutables contiene archivos regulares, vínculos simbólicos o una combinación de ambos. El árbol de runfiles puede contener vínculos simbólicos a directorios.
Las pruebas deben evitar el uso de rutas de acceso que contengan componentes ..
dentro del árbol de archivos ejecutables.
No se debe poder escribir en ningún directorio, archivo o vínculo simbólico dentro del árbol de archivos de ejecución (incluidas las rutas que atraviesan vínculos simbólicos). (De esto se deduce que el directorio de trabajo inicial no debe ser grabable). Las pruebas no deben suponer que alguna parte de los archivos ejecutables es grabable o pertenece al usuario actual (por ejemplo, chmod
y chgrp
pueden fallar).
El árbol de archivos de ejecución (incluidas las rutas de acceso que atraviesan vínculos simbólicos) no debe cambiar durante la ejecución de la prueba. Los directorios principales y los activadores del sistema de archivos no deben cambiar de ninguna manera que afecte el resultado de la resolución de una ruta de acceso dentro del árbol de runfiles.
Para detectar la salida anticipada, una prueba puede crear un archivo en la ruta de acceso especificada por TEST_PREMATURE_EXIT_FILE
al inicio y quitarlo al salir. Si Bazel ve el archivo cuando finaliza la prueba, supondrá que la prueba salió de forma prematura y la marcará como fallida.
Convenciones de etiquetado
Algunas etiquetas en las reglas de prueba tienen un significado especial. Consulta también la Enciclopedia de compilación de Bazel sobre el atributo tags
.
Etiqueta | Significado |
---|---|
exclusive |
No ejecutes ninguna otra prueba al mismo tiempo. |
external |
La prueba tiene una dependencia externa; inhabilita el almacenamiento en caché de la prueba |
large |
Convención test_suite ; conjunto de pruebas grandes |
manual * |
No incluyas el destino de prueba en patrones de destino con comodín, como
:... , :* o :all . |
medium |
Convención de test_suite ; conjunto de pruebas medianas |
small |
Convención test_suite : Conjunto de pruebas pequeñas |
smoke |
Convención test_suite , lo que significa que se debe ejecutar antes de confirmar los cambios de código en el sistema de control de versiones |
Runfiles
A continuación, supongamos que hay una regla *_binary() etiquetada como //foo/bar:unittest
, con una dependencia en tiempo de ejecución de la regla etiquetada como //deps/server:server
.
Ubicación
El directorio de archivos ejecutables de un destino //foo/bar:unittest
es el directorio $(WORKSPACE)/$(BINDIR)/foo/bar/unittest.runfiles
. Esta ruta se conoce como runfiles_dir
.
Dependencias
El directorio de archivos ejecutables se declara como una dependencia del tiempo de compilación de la regla *_binary()
. El directorio de archivos ejecutables depende del conjunto de archivos BUILD que afectan la regla *_binary()
o cualquiera de sus dependencias en tiempo de compilación o de ejecución. La modificación de los archivos fuente no afecta la estructura del directorio de archivos de ejecución y, por lo tanto, no activa ninguna recompilación.
Contenido
El directorio de archivos ejecutables contiene lo siguiente:
- Vínculos simbólicos a las dependencias de tiempo de ejecución: Cada OutputFile y CommandRule que es una dependencia de tiempo de ejecución de la regla
*_binary()
se representa con un vínculo simbólico en el directorio de runfiles. El nombre del vínculo simbólico es$(WORKSPACE)/package_name/rule_name
. Por ejemplo, el vínculo simbólico para el servidor se llamaría$(WORKSPACE)/deps/server/server
y la ruta completa sería$(WORKSPACE)/foo/bar/unittest.runfiles/$(WORKSPACE)/deps/server/server
. El destino del vínculo simbólico es el OutputFileName() del OutputFile o CommandRule, expresado como una ruta de acceso absoluta. Por lo tanto, el destino del vínculo simbólico podría ser$(WORKSPACE)/linux-dbg/deps/server/42/server
. - Vínculos simbólicos a subarchivos de ejecución: Para cada
*_binary()
Z que sea una dependencia en tiempo de ejecución de*_binary()
C, hay un segundo vínculo en el directorio de archivos de ejecución de C a los archivos de ejecución de Z. El nombre del vínculo simbólico es$(WORKSPACE)/package_name/rule_name.runfiles
. El destino del symlink es el directorio de archivos ejecutables. Por ejemplo, todos los subprogramas comparten un directorio común de archivos ejecutables.