Múltiples objetivos a partir de una receta y ejecución paralela.

Tengo un proyecto que incluye un generador de código que genera varios archivos .c y .h de un archivo de entrada con solo una invocación del generador de código. Tengo una regla que tiene los archivos .c y .h como múltiples objetivos, el archivo de entrada como requisito previo, y la receta es la invocación del generador de código. Luego tengo otras reglas para compilar y vincular los archivos .c generados.

Esto funciona bien con un factor -j de 1, pero si incremento el factor j, encuentro que recibo múltiples invocaciones del generador de código, hasta el factor -j o el número de archivos objetivo esperados, el que sea más pequeño. Esto es malo porque las múltiples invocaciones del generador de código pueden causar fallas debido a que el código generado se escribe varias veces.

No voy a publicar mi código real (grande) aquí, pero he podido construir un pequeño ejemplo que parece demostrar el mismo comportamiento.

El Makefile se ve así:

output.concat: output5 output4 output3 output2 output1
    cat $^ > $@

output1 output2 output3 output4 output5: input
    ./frob input

clean:
    rm -rf output*

En lugar de un generador de código, para este ejemplo he escrito un script de shell simple,frob que genera múltiples archivos de salida de un archivo de entrada:

#!/bin/bash

for i in {1..5}; do
    {
    echo "This is output${i}, generated from ${1}. input was:"
    cat ${1}
    } > output${i}
done

Cuando ejecuto este Makefile con factores no-unity -j, obtengo el siguiente resultado:

$ make -j2 
./frob input
./frob input
cat output5 output4 output3 output2 output1 > output.concat
$

Vemos./frob Aquí se invoca dos veces, lo que es malo. ¿Hay alguna manera en que pueda construir esta regla de modo que la receta solo se invoque una vez, incluso con un factor no-unidad-j?

He considerado cambiar la regla para que solo uno de los archivos de salida esperados sea el objetivo, luego agregar otra regla sin receta, de modo que sus objetivos sean los archivos de salida esperados restantes, y el requisito previo es el primer archivo de salida esperado. Pero no estoy seguro de que esto funcione, porque no sé si puedo garantizar el orden en que se generan los archivos y, por lo tanto, puede terminar con dependencias circulares.

Respuestas a la pregunta(4)

Su respuesta a la pregunta