2012-09-06 18 views
21

En la siguiente definición Makefile:

  1. ¿Qué significa el [email protected] en la segunda línea de la última representa?
  2. ¿Qué pasa con el símbolo | en la línea media?
define KERNEL_RULE 
$(DESTDIR)/$(1) : kernel_modules 
$(DEST_DIR)/$(1) : $(DESTDIR)/$(1) | $(DEST_DIR) 
    cp $(DESTDIR)/$(1) [email protected] 
endef 

Respuesta

52

(usted tiene una opción lamentable de los nombres de variables; vamos a cambiar DESTDIR-SOURCE_DIR y dejar DEST_DIR solo.)

Suponga que está escribiendo una regla ordinaria:

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo 
    cp $(SOURCE_DIR)/foo $(DEST_DIR)/foo 

Eso funciona, pero la redundancia es problemática. Tarde o temprano cambiará $(DEST_DIR)/foo en el preq, pero se olvida de cambiarlo en la regla. Y la regla es difícil de leer. Por eso, pusimos en una automatic variable:

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo 
    cp $(SOURCE_DIR)/foo [email protected] 

Cuando esta regla se ejecuta, [email protected] se ampliará al nombre del objetivo, $(DEST_DIR)/foo. (Podemos hacer aún mejor que eso, pero dejemos de allí.)

Ahora queremos para asegurarse de que $(DEST_DIR) existe antes de que acabe esta regla, pero no lo hacemos quieren que sea un requisito previo exactamente, porque el la ausencia de ese directorio no debería ser suficiente para hacer que esta regla se ejecute. Así que lo convierten en un order-only prerequisite:

$(DEST_DIR)/foo : $(SOURCE_DIR)/foo | $(DEST_DIR) 
    cp $(SOURCE_DIR)/foo [email protected] 

Ahora queremos muchas reglas de este tipo, para diferentes objetivos, y en lugar de hacerlo the smart way, usaremos un "canned recipe", una especie de plantilla para la creación de reglas sobre la marcha .

# This won't work 
define KERNEL_RULE 
$(SOURCE_DIR)/$(1) : kernel_modules 
$(DEST_DIR)/$(1) : $(SOURCE_DIR)/$(1) | $(DEST_DIR) 
    cp $(SOURCE_DIR)/$(1) [email protected] 
endef 

El problema es que cuando evaluamos esta definición, [email protected] se ampliará, y ya que no es una regla, sin embargo, se expandirá a nada. Así que lo cambiamos a [email protected]:

# This will work 
define KERNEL_RULE 
$(SOURCE_DIR)/$(1) : kernel_modules 
$(DEST_DIR)/$(1) : $(SOURCE_DIR)/$(1) | $(DEST_DIR) 
    cp $(SOURCE_DIR)/$(1) [email protected] 
endef 

Cuando Realizar llamadas esta definición, [email protected] se expande a [email protected], entonces si/cuando se ejecuta la regla, [email protected] se expandirá al nombre del objetivo.

+12

Nos volvemos a encontrar, y debo conceder un voto negativo reacio. El material sobre requisitos previos de solo pedido es especialmente bueno. –

+19

@JackKelly, tu amarga y renuente concesión es más valiosa para mí que cien puntos de la multitud sin rostro. – Beta

Cuestiones relacionadas