2012-07-11 9 views
6

Questo è solo un segmento di un makefile. Non capisco cosa sta succedendo.Più due punti e segno uguale nel makefile (necessità di spiegazione)

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) 
$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts 
    $(cc-command) 

Tutto quello che ho capito è queste righe compilare cpp file in .o, dopo 'print-opta', con 'cc-comando'. Ma non capisco la semantica.

Se mi espando la macro di 'OBJS', questa linea dovrebbe essere:

$(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) : $(OBJ)/%.o: $(SRC)/%.cpp | print-opts 
    $(cc-command) 

A me, sembra che a '$ (SRCS:. $ (SRC) /% cpp = $ (OBJ) /%. o) ', afferma che tutti i .cpp in $ (SRC) verrebbero a .o in $ (OBJ), ma questo dipenderebbe da $ (OBJ) /%. o, che dipende da $ (SRC) /%.cpp. Questo non ha senso ...

Non capisco qual è il significato del segno di uguale qui, e cosa significano più punti.

risposta

14

Supponiamo di aver definito queste tre variabili (e se non l'hai, la regola non funziona molto bene):

SRC = source_dir 
OBJ = object_dir 
SRCS = source_dir/foo.cpp source_dir/bar.cpp 

Ora consideriamo l'assegnazione

OBJS = $(SRCS:$(SRC)/%.cpp=$(OBJ)/%.o) 

Questo è a substitution reference; si dice "per qualsiasi cosa in , con il valore $(OBJ)/%.o", nel formato $(OBJ)/%.o ". Quindi OBJS valuterà a object_dir/foo.o object_dir/bar.o.

Ora la regola:

$(OBJS):$(OBJ)/%.o: $(SRC)/%.cpp | print-opts 
    $(cc-command) 

Thuis è un static pattern rule. Specifica un elenco di destinazioni ($(OBJS)), un modello di destinazione ($(OBJ)/%.o) e un modello prerequisito ($(SRC)/%.cpp). Crea corrispondenze con un obiettivo per il modello di destinazione e lo usa per costruire il nome del prerequisito. Quindi, se si utilizza questa regola per creare object_dir/foo.o, lo stelo sarebbe foo e il prerequisito sarebbe source_dir/foo.cpp.

(non hai chiesto circa | print-opts, quindi immagino che è già chiaro.)

+0

Grazie mille. Anche i riferimenti al manuale di make di gnu sono molto utili. (Avevo già letto questo manuale, ma non sono riuscito a trovare le informazioni necessarie) – qinsoon

+0

Tad confuso dal riferimento di sostituzione. Quindi, se ho 'main.c', lo inserirò nella directory dei file dell'oggetto e cambierà semplicemente l'estensione del file in' .o'. Questo conserva il contenuto del file e cambia semplicemente l'estensione. Questo imposta i nomi per tutti i file oggetto con cui verremmo a finire. Quindi usiamo la lista dei nomi come destinazione e compiliamo i file oggetto, e sovrascriviamo i file con il nuovo file oggetto che abbiamo appena compilato. Corretta? – Ungeheuer

+0

@Ungeheuer: No, il riferimento di sostituzione non fa assolutamente nulla per i file, si limita a trasformare le variabili. Diventa "source_dir/main.cpp" in "object_dir/main.o"; quelli sono * nomi di file *, non * file *. Una volta che abbiamo la stringa "object_dir/main.o", possiamo passarla alla regola del pattern, che sa come costruire un file con quel nome. – Beta

Problemi correlati