2009-10-30 13 views

Respuesta

4

Claro, si yo uso make -j a, todos ellos podrían quedar incorporado al mismo tiempo (dependiendo de si b, c, d, o e a su vez tienen otras dependencias/interrelacionados).

+1

Esto realmente no responde la pregunta, así que me sorprende que haya sido aceptado. –

+3

La pregunta que leí allí es "Parece que generalmente se realizarán en orden' b', 'c',' d', 'e', pero ¿puede suceder que el orden sea diferente?". Estoy bastante seguro de que proporcioné un contraejemplo. Tu opinión puede variar, supongo. –

+0

* prerrequisitos de solo pedido * ** están ** compilados en un orden particular. Sin embargo, no estoy seguro de si el póster sabía que había algo más que * requisitos previos * basados ​​en su suposición. – jww

6

En el pedido derecho, según las reglas que proporcione. Para su ejemplo particular, eso podría significar cualquiera de una serie de órdenes diferentes (4! = 24, de memoria).

Todos los programas de make son libres de elegir el orden que deseen, siempre que se respeten las dependencias. Si hubiera otras reglas en su ejemplo, digamos c: b, entonces c se haría antes del b (pero ese no es el caso, como usted señala).

Si necesita confiar en un pedido específico, necesitará más reglas para aplicarlo. De lo contrario, make puede hacer lo que le plazca. El documentation para GNU Make solo indica cómo se procesan las reglas , no el orden en el que se procesan las dependencias dentro de una regla. El orden más lógico (para mí, de todos modos) sería el orden en el que están en la lista, pero eso no está garantizado.

21

No, la orden no está definida. Ese es el total de punto en el uso de la programación orientada a la dependencia declarativa: que la computadora puede elegir el orden de evaluación óptimo, o de hecho, evaluarlos incluso al mismo tiempo.

4

No, no puede contar con el pedido cuando no hay relaciones de dependencia.

  • necesita hacer a topological sort, porque las dependencias pueden tener relaciones adicionales y múltiples. El tipo que hacer hace es potencialmente bastante complejo, como nodos en el gráfico pueden estar relacionados varias veces en diferentes niveles
  • en algoritmos de clasificación generales no son naturalmente stable, incluso para simples tipo basados ​​en claves
12

¿En qué orden se harán los requisitos previos por parte de GNU?

Depende del tipo de requisito previo. De acuerdo con el GNU Make Manual, Sección 4.2:

En realidad, hay dos tipos diferentes de requisitos previos entendidos por GNU Marca: requisitos previos normales tales como los descritos en la sección anterior , y el orden de sólo requisitos previos. Un requisito previo normal es hacer dos declaraciones : en primer lugar, impone un orden en el que se invocarán las recetas : las recetas para todos los requisitos previos de un objetivo serán completadas antes de ejecutar la receta del objetivo. En segundo lugar, impone una relación de dependencia: si algún requisito previo es más nuevo que el objetivo , el objetivo se considera obsoleto y debe reconstruirse.

Normalmente, esto es exactamente lo que desea: si el requisito previo de un objetivo es actualizado, entonces el objetivo también debe actualizarse.

Ocasionalmente, sin embargo, se tiene una situación en la que desea imponer un orden específico sobre las reglas que se invoca sin forzar el objetivo ser actualizado si se ejecuta una de esas reglas. En ese caso, usted quiere definir requisitos de orden previos. Los requisitos previos de pedido se pueden especificar colocando un símbolo de tubería (|) en la lista de requisitos previos : los requisitos previos a la izquierda del símbolo de tubería son normales; los requisitos previos a la derecha son orden de sólo:

targets: normal-prerequisites | order-only-prerequisites 

La sección de requisitos previos normal puede por supuesto estar vacío. Además, puede declarar varias líneas de requisitos previos para el mismo destino: se anexan correctamente (los requisitos previos normales se anexan a la lista de requisitos previos normales; los requisitos previos de pedido son añadidos a la lista de requisitos previos de solo pedido) . Tenga en cuenta que si declara que el mismo archivo es un requisito previo normal y solo de orden , el prerrequisito normal tiene prioridad (ya que tiene un superconjunto estricto del comportamiento de un requisito previo solo de pedido).

Considere un ejemplo en el que sus objetivos se colocarán en un directorio separado , y ese directorio podría no existir antes de ejecutar make. En esta situación, desea que el directorio se cree antes de que se coloquen los objetivos pero, como las marcas de tiempo en los directorios cambian cada vez que se agrega, elimina o renombra un archivo, sin duda no queremos reconstruir todo los objetivos cada vez que cambia la marca de tiempo del directorio. Una manera de manejar esto es con la orden de sólo requisitos previos: hacer que el directorio de una orden de sólo un requisito previo en todos los los objetivos:

OBJDIR := objdir 
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o) 

$(OBJDIR)/%.o : %.c 
    $(COMPILE.c) $(OUTPUT_OPTION) $< 

all: $(OBJS) 

$(OBJS): | $(OBJDIR) 

$(OBJDIR): 
    mkdir $(OBJDIR) 

Ahora la regla para crear el directorio 'objdir' se ejecute, si es necesario , antes de que se genere '.o', pero no se generará '.o' porque la marca de tiempo del directorio 'objdir' ha cambiado.

+5

Sin embargo, esto realmente no impone un pedido, al menos no más que un requisito previo normal. Solo dice que para un requisito previo solo de orden, gmake debe ignorar la marca de tiempo. Es un requisito previo, por lo que debe existir antes de poder ejecutar la regla actual, pero dado que es un requisito previo solo de orden, su marca de tiempo/estado no activa la regla actual. (Lo cual no excluye otras dependencias que causan que las dependencias de solo orden ejecuten sus comandos.) – simpleuser

+2

De la documentación de gnu make anterior: 'Ocasionalmente, sin embargo, tiene una situación en la que desea imponer un orden específico sobre cómo las reglas de se invocará un objetivo sin forzar que el objetivo se actualice si se ejecuta una de esas reglas. Esto parece bastante mal redactado para lo que realmente hace el prerrequisito de solo oder. Hasta donde entiendo, un prerrequisito de solo pedido es simplemente un requisito previo que no obliga a 'make' a reconstruir el objetivo si cambia. – SebNag

0

Si el orden es importante, puede aplicarlo de manera selectiva usando recursive make. Por ejemplo, suponga que no le importa en qué orden B y C están hechos, siempre y cuando ambos estén hechos antes de que d y d se hagan antes de e.Posteriormente, se podría escribir la regla como:

a: b c 
    $(MAKE) d 
    $(MAKE) e 
    # Additional steps to make a 

Tenga en cuenta que dependiendo de la complejidad de D y E, este enfoque puede hacer malas cosas a sus tiempos de construcción: ver Recursive Make Considered Harmful (PDF) para los argumentos en contra de hacerlo de esta manera .

Cuestiones relacionadas