Idioma: 日本語 | Español | Français | Português | 中文 | English
Anterior | Siguiente | Índice | Original en inglés (gnu.org)

13 Integrar GNU make (interacción con otros programas)

GNU make suele ser uno de los componentes de un conjunto de herramientas mayor, como los entornos de desarrollo integrados (IDE) o las cadenas de herramientas de los compiladores. El papel de make consiste en lanzar órdenes y determinar si han tenido éxito o no. Para cumplir solo con ese cometido no se necesita ningún mecanismo especial de integración. Sin embargo, a veces resulta conveniente vincular make de forma más estrecha con otras partes del sistema. Esto incluye tanto la integración con las herramientas de nivel superior (las que invocan a make) como con las de nivel inferior (las que make invoca).

13.1 Compartir slots de trabajo con GNU make

GNU make tiene la capacidad de ejecutar varias recetas (recipes) en paralelo (consulte Ejecución en paralelo) y, además, de fijar un límite al número total de trabajos paralelos incluso a través de las invocaciones recursivas de make (consulte Comunicar opciones a un sub-make). Algunas de las herramientas que make invoca también son capaces de ejecutar varias operaciones en paralelo, ya sea usando varios hilos o varios procesos. Si se amplían esas herramientas para que participen en el mecanismo de gestión de trabajos de GNU make, se puede garantizar que el número total de hilos/procesos activos en el sistema no supere el número máximo de slots concedido a GNU make.

GNU make emplea un método llamado «jobserver» para controlar el número de trabajos activos a través de las invocaciones recursivas. La implementación concreta del jobserver varía según el sistema operativo, pero algunos aspectos fundamentales son siempre comunes.

En primer lugar, make proporciona a sus procesos hijos la información necesaria para acceder al jobserver a través de la variable de entorno MAKEFLAGS. Las herramientas que deseen participar en el protocolo del jobserver deberán analizar esta variable de entorno y localizar la palabra que comienza por --jobserver-auth=. El valor de esta opción describe cómo comunicarse con el jobserver. La interpretación de este valor se explica en los apartados siguientes.

Tenga en cuenta que la variable MAKEFLAGS puede contener varias instancias de la opción --jobserver-auth=. Solo es relevante la última instancia.

En segundo lugar, toda orden que make lanza tiene reservado de antemano un slot de trabajo implícito antes de iniciarse. Cualquier herramienta que desee participar en el protocolo del jobserver puede dar por hecho que siempre puede ejecutar un trabajo sin necesidad de contactar en absoluto con el jobserver.

Por último, es crucial que las herramientas que participan en el protocolo del jobserver devuelvan al jobserver el número exacto de slots que obtuvieron de él antes de terminar, incluso en condiciones de error. ¡Recuerde que el slot de trabajo implícito no debe devolverse al jobserver! Devolver demasiados pocos slots significa que esos slots se perderán durante el resto del proceso de construcción; devolver demasiados slots significa que habrá slots adicionales disponibles. La orden make de nivel superior mostrará un mensaje de error al final de la construcción si detecta un número incorrecto de slots disponibles en el jobserver.

A modo de ejemplo, supongamos que está implementando un enlazador (linker) que ofrece funcionamiento multihilo. Le gustaría mejorar el enlazador para que, cuando lo invoque GNU make, participe en el protocolo del jobserver y así controlar cuántos hilos se usan durante el enlazado. Primero deberá modificar el enlazador para que determine si la variable de entorno MAKEFLAGS está definida. A continuación deberá analizar el valor de esa variable para determinar si el jobserver está disponible y cómo acceder a él. Si lo está, podrá acceder a él para obtener slots de trabajo que controlen cuánto paralelismo puede usar su herramienta. Una vez terminado el trabajo, su herramienta deberá devolver esos slots de trabajo al jobserver.

13.1.1 Interacción con el jobserver en POSIX

En los sistemas POSIX, el jobserver se implementa de una de estas dos maneras. En los sistemas que lo admiten, GNU make crea una tubería con nombre (named pipe) y la usa como jobserver. En este caso, la opción de autenticación tiene la forma --jobserver-auth=fifo:PATH, donde «PATH» es el nombre de ruta de la tubería con nombre. Para acceder al jobserver debe abrir la ruta de la tubería con nombre y leer/escribir en ella tal como se describe a continuación.

Si el sistema no admite tuberías con nombre, o si el usuario ha proporcionado la opción --jobserver-style y ha especificado «pipe», el jobserver se implementa como una simple tubería UNIX. En este caso, la opción de autenticación tiene la forma --jobserver-auth=R,W, donde «R» y «W» son enteros no negativos que representan descriptores de archivo: «R» es el descriptor de archivo de lectura y «W» es el descriptor de archivo de escritura. Si uno de estos descriptores de archivo, o ambos, son negativos, significa que el jobserver está desactivado para este proceso.

Cuando se usa una tubería simple, solo tienen acceso al jobserver aquellas líneas de orden que make reconoce como invocaciones recursivas de make (consulte Cómo funciona la variable MAKE). Al escribir los makefiles debe asegurarse de marcar la orden como recursiva (lo más habitual es anteponer el indicador + a la línea de orden; consulte Uso recursivo de make). Tenga en cuenta que el lado de lectura de la tubería del jobserver está configurado en modo «bloqueante» (blocking). Esto no debe modificarse.

En ambas implementaciones del jobserver, la tubería viene precargada con un token de un solo carácter por cada trabajo disponible. Para obtener un slot adicional debe leer un único carácter del jobserver; para liberar un slot debe escribir un único carácter de vuelta en el jobserver.

Es importante que, al liberar el slot de trabajo, escriba de vuelta el mismo carácter que leyó. No dé por supuesto que todos los tokens son el mismo carácter; caracteres distintos pueden tener significados distintos para GNU make. El orden no importa, ya que make no tiene ninguna idea de en qué orden se completarán los trabajos.

Hay diversas condiciones de error que debe tener en cuenta para garantizar que su implementación sea robusta:

13.1.2 Interacción con el jobserver en Windows

En los sistemas Windows, el jobserver se implementa como un semáforo con nombre (named semaphore). El semáforo se configura con un recuento inicial igual al número de slots disponibles; para obtener un slot debe esperar (wait) en el semáforo (con o sin tiempo de espera). Para liberar un slot, libere (release) el semáforo.

Para acceder al semáforo debe analizar la variable MAKEFLAGS y buscar la cadena de argumento --jobserver-auth=NAME, donde «NAME» es el nombre del semáforo con nombre. Pase este nombre a OpenSemaphore para crear un manejador (handle) del semáforo.

El único estilo válido para --jobserver-style es «sem».

Hay diversas condiciones de error que debe tener en cuenta para garantizar que su implementación sea robusta:

13.2 Sincronizar la salida del terminal

Normalmente, GNU make lanza todas las órdenes con acceso a las mismas salidas estándar y de error con las que se inició el propio make. Numerosas herramientas detectan si la salida es un terminal o no lo es, y utilizan esta información para cambiar el estilo de la salida. Por ejemplo, si la salida va a un terminal, la herramienta puede añadir caracteres de control que establecen el color o incluso cambian la posición del cursor. Si la salida no va a un terminal, esos caracteres de control especiales no se emiten, para que no corrompan los archivos de registro, etc.

La opción --output-sync (consulte La salida durante la ejecución en paralelo) anula esta detección del terminal. Cuando la sincronización de la salida está activada, GNU make dispone que toda la salida de las órdenes se escriba en un archivo, de modo que su salida pueda escribirse como un bloque sin interferencias de otras órdenes. Esto significa que todas las herramientas invocadas por make creerán que su salida no se va a mostrar en un terminal, aun cuando vaya a hacerlo (porque make la mostrará allí una vez completada la orden).

Para facilitar la tarea a las herramientas que deseen determinar si su salida se mostrará o no en un terminal, GNU make define las variables de entorno MAKE_TERMOUT y MAKE_TERMERR antes de invocar cualquier orden. Las herramientas que deseen determinar si la salida estándar (o la de error, respectivamente) se mostrará en un terminal pueden comprobar si estas variables de entorno existen y contienen un valor no vacío. Si es así, la herramienta puede suponer que la salida se mostrará (con el tiempo) en un terminal. Si las variables no están definidas o tienen un valor vacío, la herramienta debe recurrir a sus métodos habituales para detectar si la salida va a un terminal o no.

Se puede analizar el contenido de estas variables para determinar el tipo de terminal que se usará para mostrar la salida.

De forma análoga, los entornos que invocan a make y que desean capturar la salida para mostrarla finalmente en un terminal (o en algún dispositivo de visualización capaz de interpretar los caracteres de control de terminal) pueden definir estas variables antes de invocar a make. GNU make no modificará estas variables de entorno si ya existen cuando se inicia.


Anterior | Siguiente | Índice | Original en inglés (gnu.org)