Watch at EaseHistorias. Respuestas. Perspectiva.

Tecnología · GUÍA PRÁCTICA

¿GNU make dice jobserver unavailable? Prueba el límite recursivo antes de añadir -j

El make hijo cayó a un solo trabajo porque no heredó la coordinación. Traza la primera receta o envoltorio, repara solo un límite consciente y mide el máximo compartido.

Ilustración editorial original de un jobserver compartido con un hijo desconectado.
Ilustración original de Watch at Ease: traza el primer hijo que pierde el canal compartido. Watch at Ease

El aviso “jobserver unavailable: using -j1” de GNU make significa que un make hijo no heredó suficiente conexión del jobserver del padre y continúa en serie. No demuestra un fallo del compilador ni que cada capa necesite su propio -j.

Encuentra la primera frontera donde se pierde la coordinación. Usa $(MAKE) en una receta recursiva real, + solo cuando haga falta para reconocerla y declara consciente a un envoltorio solo si implementa el protocolo. Verifica todo bajo un único límite superior.

1. Captura la primera frontera perdida

Ejecuta una compilación controlada con el comando superior original. Conserva primer aviso, nivel, comando padre, versiones, generador, árbol de procesos y forma de MAKEFLAGS. Los avisos posteriores suelen ser consecuencia; la primera pérdida asigna la frontera.

Distingue receta directa, script shell, comando personalizado CMake, envoltorio de lenguaje y entrada de contenedor. No publiques descriptores vivos ni copies sus valores a otra orden.

2. Lee el aviso como fallo de coordinación

GNU make comunica acceso por MAKEFLAGS y reserva una ranura implícita por comando. Los makes recursivos reconocidos comparten el techo superior.

Si el padre no identifica otro make, el hijo recibe información incompleta. Con tuberías pierde acceso a descriptores, emite el aviso y sigue secuencialmente con -j1.

3. Repara una receta make recursiva directa

Si el hijo es make, usa $(MAKE) directamente en la receta y no el nombre literal. Conserva el ejecutable del padre y la semántica recursiva documentada.

El prefijo + puede marcar una llamada oculta, pero también cambia dry-run, touch y question. Úsalo solo con indirección o un envoltorio que implemente el protocolo.

4. Trata envoltorios y CMake explícitamente

Si un envoltorio lanza al hijo, comprueba que conserva MAKEFLAGS y el canal vivo. Nunca inventes --jobserver-auth ni reutilices números de descriptor fuera del padre.

CMake puede aplicar JOB_SERVER_AWARE con generadores Makefile compatibles. Actívalo solo para comandos participantes; Ninja y otros usan mecanismos distintos.

5. Rechaza -j independientes anidados por defecto

No elimines el aviso añadiendo -jN a todos los sub-makes. Un -j numérico forzado desactiva el modo compartido y permite que el árbol supere CPU o memoria.

Mantén el paralelismo en el nivel superior cuando sea posible. Si un envoltorio necesita otro límite, documenta propietario, generador, versiones y techo de recursos.

6. Verifica el límite compartido y la compilación

Repite el mismo objetivo limpio con un -j superior fijo. Exige que desaparezca el primer aviso, mide el máximo de procesos y trabajo solapado, CPU, memoria y tiempo sin confundir velocidad con corrección.

Ejecuta pruebas normales y una compilación equivalente a CI o con poca memoria. Revisa dry-run, conserva órdenes anterior y posterior, estructura saneada de MAKEFLAGS y registros para revisar o revertir.

Ilustración editorial original de una desarrolladora reparando una frontera recursiva.
Ilustración original de Watch at Ease: restaura la coordinación en la frontera propietaria y mide el límite. Watch at Ease