2011-08-16 17 views
24

Duplicar posibles:
GNU Makefile rule generating a few targets from a single source fileGNU make: objetivos múltiples en una sola regla

Si tengo una regla Makefile así:

a b c: 
    echo "Creating a b c" 
    touch a b c 

output: a b c 
    cat a b c > output 

y corro make -j9 output

make ve las 3 dependencias (a, b, c), busca cómo producirlas: (la regla "a b c" anterior), pero ¿qué pasa después? ¿No debería darse cuenta de que la regla "a b c" solo necesita ejecutarse una vez para crear los 3 objetivos?

Esto es lo que hacen en realidad hace:

[[email protected] test]$ make -j9 output -n 
echo "Creating a b c" 
touch a b c 
echo "Creating a b c" 
touch a b c 
echo "Creating a b c" 
touch a b c                                                                  
cat a b c > output                                                                
[[email protected] test]$ 

La misma receta se ejecuta 3 veces, una vez para cada dependencia de gobernar "de salida"!

¿Alguien sabe por qué se comporta de esta manera?

+0

Relacionado: http: // stackoverflow.com/questions/3016258/generate-multiple-target-using-single-action-rule y http://stackoverflow.com/questions/2973445/gnu-makefile-rule-generating-a-few-targets-from-a- archivo de una sola fuente – krlmlr

Respuesta

27

Su regla a b c: le dice a make que esto es cómo construir cualquier de estos objetivos, no cómo construir todo de ellos. Make no es lo suficientemente inteligente como para analizar los comandos y deducir que ejecutar la regla una vez construirá los tres. Hacer sabe (de la regla output) que debe reconstruir a, b y c, así que eso es lo que hace. Ejecuta la primera regla una vez para a, una vez para b y una vez para c.

Si desea reconstruir de forma individual, haga lo siguiente:

a b c: 
    echo "Creating [email protected]" 
    touch [email protected] 

Si desea reconstruir todos a la vez, hacer algo como esto:

.PHONY: things 
things: 
    echo "Creating a b c" 
    touch a b c 

output: things 
    cat a b c > output 

o mejor aún:

THINGS = a b c 
.PHONY: things 
things: 
    echo "Creating $(THINGS)" 
    touch $(THINGS) 

output: things 
    cat $(THINGS) > output 
+2

¡Excelente respuesta! Gracias. ¿Es la creación de un objetivo falso de la única manera, o existe una forma más limpia de expresar "a ** y ** b ** y ** c" según esta regla "? – Pavel

+0

@Pavel, no sé de una manera más limpia (y de todos modos tomaría la primera opción). Pero, de nuevo, sigo intentando descubrir la respuesta de AUZKamath. – Beta

+12

Consulte http://www.cmcrossroads.com/ask-mr-make/12908-rules-with-multiple-outputs-in-gnu-make para obtener una encuesta de métodos para hacer frente a este escenario, incluido el único "correcto" forma de especificar una regla con múltiples salidas en gmake (reglas de patrones, por supuesto!). –

6

abc son tres objetivos/metas diferentes sin requisitos previos. Yo, e decir que construirá el objetivo cada vez que se le pida.

a b c: 
    echo "Creating a b c" 
    touch a b c 

Usted está pidiendo que make genere el resultado designado del objetivo que tiene una b c como requisitos previos. Entonces los objetivos a b c se construyen secuencialmente y finalmente se genera la salida.

Ahora, en su caso, todos los objetivos se crean invariablemente cuando se llama a uno de ellos. Por lo tanto, para evitar construcciones redundantes, deberá agregar requisitos previos a los destinos a, b, c. Construya el objetivo 'a' solo si 'a' no existe. Del mismo modo para 'b' y 'c'

a b c: [email protected] 
    echo "Creating a b c" 
    touch a b c 

Sin embargo, esto no es aconsejable. Lo ideal es que los objetivos de Makefile sean muy específicos.

+2

Esto funciona, pero no puedo ver cómo. ¿Jack Kelly te envió? – Beta

+1

Sin embargo, al ejecutar esto con 'make -j3 a b c', se crean tres trabajos. – krlmlr

+2

¿Alguien puede explicar cómo funciona esto? No puedo explicarlo leyendo https://www.gnu.org/software/make/manual/make.html#index-_0024_0040 – Xiphias

Cuestiones relacionadas