2012-09-06 11 views
21

Nella seguente definizione Makefile:

  1. Cosa significa il [email protected] nella penultima riga stand for?
  2. E il simbolo | nella linea centrale?
define KERNEL_RULE 
$(DESTDIR)/$(1) : kernel_modules 
$(DEST_DIR)/$(1) : $(DESTDIR)/$(1) | $(DEST_DIR) 
    cp $(DESTDIR)/$(1) [email protected] 
endef 

risposta

52

(avete una scelta deprecabile di nomi di variabili; cambiamo DESTDIR-SOURCE_DIR e lasciare DEST_DIR da sola.)

Supponiamo si stesse scrivendo una regola ordinaria:

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

Funziona, ma la ridondanza è problematica. Prima o poi cambierai $(DEST_DIR)/foo nel preq ma dimenticarti di cambiarlo nella regola. E la regola è difficile da leggere. Così abbiamo messo in un automatic variable:

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

Quando questa regola viene eseguito, [email protected] sarà ampliato al nome del target, $(DEST_DIR)/foo. (Possiamo fare anche di meglio, ma fermiamoci lì.)

Ora vogliamo fare in modo che $(DEST_DIR) esiste prima di questa regola viene eseguita, ma non vogliono che sia un prerequisito esattamente, perché la l'assenza di tale directory non dovrebbe essere sufficiente per far funzionare questa regola. Così rendiamo un order-only prerequisite:

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

Ora vogliamo molte regole come questo, per target diversi, e invece di farlo the smart way, useremo un "canned recipe", una sorta di modello per la creazione di regole al volo .

# 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 

Il problema è che quando valutiamo questa definizione, sarà ampliato [email protected], e dal momento che non è ancora una regola, si espanderà a nulla. Quindi cambiamo 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 

Quando Effettuare chiamate questa definizione, [email protected] espande a [email protected], poi se/quando viene eseguito la regola, [email protected] si espanderà per il nome della destinazione.

+12

Ci vediamo di nuovo, e devo concedere un riluttante voto positivo. La roba sui prerequisiti di solo ordine è particolarmente buona. –

+19

@JackKelly, la tua amara e riluttante concessione mi è più preziosa di cento punti dalla folla senza volto. – Beta