2011-02-23 12 views
15

Encontré este makefile en este site. No explican este ejemplo, así que me preguntaba si alguien nuevo estaba pasando lo que estaba pasando.¿Podría alguien explicar este archivo de make?

CC=g++ 
CFLAGS=-c -Wall 
LDFLAGS= 
SOURCES=main.cpp hello.cpp factorial.cpp 
OBJECTS=$(SOURCES:.cpp=.o) 
EXECUTABLE=hello 

all: $(SOURCES) $(EXECUTABLE) 

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(LDFLAGS) $(OBJECTS) -o [email protected] 

.cpp.o: 
    $(CC) $(CFLAGS) $< -o [email protected] 
+0

Las primeras líneas, como señala Chris, definen las abreviaturas, el resto es un "gráfico de dependencia". Cuando cambie sus archivos fuente, el sistema 'make' comenzará a ejecutar las reglas de abajo hacia arriba para llegar al resultado final, creando finalmente un ejecutable actualizado' hello' compilado. – Recct

Respuesta

28
CC=g++ 
CFLAGS=-c -Wall 
LDFLAGS= 
SOURCES=main.cpp hello.cpp factorial.cpp 

conjuntos de cuatro variables que se van cadenas constantes. Para el resto de la makefile, donde $(CC) aparece (por ejemplo), que serán reemplazados por g++

OBJECTS=$(SOURCES:.cpp=.o) 

establece los objetos variables a ser el mismo como fuentes, excepto donde el patrón .cpp aparece en una palabras de las fuentes , la sustituye por .o

EXECUTABLE=hello 

conjuntos otra cadena constante var

all: $(SOURCES) $(EXECUTABLE) 

Th La primera regla actual en el archivo MAKE, esto le dice a la estructura all que primero debe compilar todo en $(SOURCES) y $(EXECUTABLE), y luego no hacer nada. Dado que esta es la primera, se convierte en el destino predeterminado, por lo que ejecutar make es equivalente a make all

$(EXECUTABLE): $(OBJECTS) 
     $(CC) $(LDFLAGS) $(OBJECTS) -o [email protected] 

Otra regla: para crear $(EXECUTABLE) (que se expande a hello) se debe construir la primera todo en $(OBJECTS) (equivalente a main.o hello.o factorial.o) y a continuación, ejecute el comando $(CC) $(LDFLAGS) $(OBJECTS) -o [email protected]

.cpp.o: 
     $(CC) $(CFLAGS) -o [email protected] $< 

una regla patrón: con el fin de construir un archivo que termina en .o, primero reconstruir/crear/encontrar el archivo correspondiente que termina en .cpp y ejecute el comando $(CC) $(CFLAGS) -o [email protected] $<.

Estas dos últimas reglas contienen las variables especiales [email protected] y $< que sólo son válidos en acciones de las reglas y ampliar hasta el objetivo y la primera dependencia, respectivamente

Así que cuando se ejecuta make, se lee todo esto y luego trata de construir el objetivo predeterminado (todo). Como no existe, intenta compilar los archivos main.cpp, hello.cpp, factorial.cpp y hello. Dado que los primeros 3 (presumiblemente) existen, busca reglas/dependencias para ellos, pero no encuentra ninguno, por lo que decide que no hay nada que hacer por ellos. Si no existieran, make daría un error diciendo "no rule to make target 'main.cpp'"

En el caso de "hola" depende de main.o, hello.o y factorial.o , entonces los mira a ellos. Para main.o, la regla de patrón dice que depende de main.cpp, por lo que si main.o no existe o si main.cpp es más reciente, ejecutará el comando g++ -c -Wall -o main.o main.cpp. Lo mismo ocurre con hello.o y factorial.o.

Una vez hecho esto, si hello no existe o es anterior a cualquiera de esos archivos .o (que pueden haber cambiado recientemente, por lo que posiblemente sean bastante nuevos), ejecutará ese comando para volver a vincularlo. Finalmente, ejecutará el comando vacío (sin hacer nada) para 'reconstruir' todo.

+0

Lo único que no entiendo es por qué en la regla de patrón es necesario volver a llamar '-o $ @'. ¿Puedes explicarme esto? Gracias – Kyrol

+0

@Kyrol: '-o' especifica el nombre del archivo para escribir. En algunos compiladores, el archivo de salida predeterminado ya puede ser el mismo que el objetivo, pero el rescindir no duele. –

+0

¿No es '.cpp.o:' una regla de sufijo y no una regla de patrón? – jdknight

Cuestiones relacionadas