2012-02-06 6 views
18

En un makefile, la línea de dependencia es de la forma -Orden de componentes de procesamiento en makefile

abc: x y z 

Los tres de los componentes (x, y, z) son en sí mismos objetivos en líneas de dependencia más abajo en el makefile

Si se invoca make abc, ¿en qué orden se ejecutarán los tres destinos x, y, z?

+0

posible duplicado de [¿En qué orden los requisitos serán hechos por la marca GNU?] (http://stackoverflow.com/questions/1647480/in-what-order-prerequisites-will- be-made-by-the-gnu-make) – Mike

Respuesta

26

De forma predeterminada, el orden de ejecución es el mismo que el especificado en la lista de requisitos previos, a menos que existan dependencias definidas entre estos requisitos previos.

abc: x y z 

La orden es x y z.

abc: x y z 
y : z 

La orden sería x z y.

Pero, idealmente, debe diseñar sus Makefiles para que no confíe en el orden en que se especifican los requisitos previos. Es decir, si y se debe ejecutar después de z, existe que debe ser una dependencia de y : z.

Y tenga en cuenta que GNU Make puede ejecutar algunas recetas en paralelo, consulte Mat's answer.

+1

Gracias, respuesta clara. ¿Por qué hay una 'UPD'? ¿ahí? –

+2

@Shailesh, de nada. He agregado y UPD. sección después de publicar la respuesta principal. –

+0

@EldarAbusalimov: No es necesario, hay un historial de revisiones. Solo haz que la respuesta sea una sola y cohesiva prosa. –

28

Realmente no debe depender del orden en el que se ejecutan; si todo lo demás sigue igual, las tres recetas para esos requisitos previos podrían ejecutarse en paralelo.

La única regla estricta es que se deben cumplir todos los requisitos previos antes de ejecutar la receta de destino.

Si no hay dependencias entre x, y y z, y ninguna ejecución en paralelo, GNU make parece ejecutarlos en el orden en que se ha especificado, pero esto no está garantizado en la documentación.

+0

Respuesta breve y clara. No puedo '+ 1' en este momento, pero intentaré no olvidar volver y votar mañana. –

+3

Otra forma de decir esto: siempre que * hay * una dependencia de orden, hágalo explícito como una regla Makefile. – reinierpost

+0

'receta' es el término usado para denotar la lista de comandos bajo una línea de dependencia? –

15

La descripción de POSIX make incluye una lógica que dice:

Los make los servicios públicos en la mayoría de las implementaciones históricos procesan los requisitos previos de un objetivo en orden de izquierda a derecha, y el formato de archivo MAKE requiere esto. Es compatible con el idioma estándar utilizado en muchos makefiles que producen programas yacc; por ejemplo:

foo: y.tab.o lex.o main.o 
    $(CC) $(CFLAGS) -o [email protected] t.tab.o lex.o main.o 

En este ejemplo, si make eligieron cualquier orden arbitrario, el lex.o podría no hacerse con la correcta y.tab.h. Aunque puede haber mejores formas de expresar esta relación, es ampliamente utilizado históricamente. Las implementaciones que deseen actualizar los requisitos previos en paralelo deben requerir una extensión explícita a make o el formato de archivo MAKE para lograrlo, como se describió anteriormente.

(creo que el t.tab.o en la línea $(CC) es un error tipográfico para y.tab.o, pero eso es lo que la lógica dice en realidad.)

Por lo tanto, el comportamiento observado de que los requisitos previos se procesen de izquierda a derecha tiene validación aquí, aunque solo se encuentra en la sección de Justificación, no en la descripción principal. La Razón también menciona problemas con paralelos make etc.

+0

+1 para la descripción POSIX y la advertencia importante sobre los trabajos paralelos 'make '. IMO, la opción de no permitir la ejecución de cualquier orden en trabajos paralelos fue un paso en falso. _e.g._ Me complace que mis '.o'bjects se compilen en cualquier orden, pero necesito muchas otras cosas antes y después de compilar y enlazar, y es mucho más difícil de lo que debería ser ... –

-1

De https://stackoverflow.com/a/22638294/636849, se puede añadir el símbolo de canalización:

abc: | x y z 

De manual de make: requisitos previos orden sólo se puede especificar mediante la colocación de un símbolo de canalización (|) en la lista de requisitos previos: cualquier prerrequisito a la izquierda del símbolo de tubería es normal; cualquier prerrequisito a la derecha es solo de orden:

objetivos: requisitos previos normales | solo-prerrequisitos de orden

+1

No, eso no es lo que hacen los requisitos previos de solo pedido. 'foo: | bar baz' no impone 'bar baz' más que sin el carácter de pipa. En cambio, la tubería dice más o menos que "al pedir foo, bar y baz, bar y baz deben aparecer antes que foo, pero las actualizaciones de bar y baz no son motivo suficiente para hacer que foo se considere actualizado y necesite ejecutarse". Los documentos están en https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html y no son los más claros. –