2009-12-30 5 views
6

Soy nuevo en Makefiles y g ++ y me golpea un problema al generar dependencias de los archivos de proyecto usando el indicador -MM. Estoy publicando el Makefile que estoy usando para su consideración. Por favor echa un vistazo.Problema que genera dependencias en Makefile usando -MM

OUTPUT_ROOT := output/ 
SOURCE_ROOT := source/ 

TITLE_NAME := TestProj 

SOURCES := \ 
MyFile.cpp \ 
stdAfx.cpp \ 
Main.cpp \ 

OUT_DIR := $(OUTPUT_ROOT) 

OUT_O_DIR := $(OUT_DIR) 

OBJS = $(SOURCES:%.cpp=$(OUT_O_DIR)%.o) 
DEPS = $(OBJS:%.o=%.d) 
DIRS = $(subst /,/,$(sort $(dir $(OBJS)))) 
SOURCE_TARGET = $(SOURCES:%.cpp=$(SOURCE_ROOT)%.cpp) 
OUTPUT_TARGET = $(OUT_DIR)$(TITLE_NAME) 

#--------------------------------------------------------------------- 
# executables 
#--------------------------------------------------------------------- 
MD := mkdir -p 
RM := rm 
CC := g++ 

#--------------------------------------------------------------------- 
# rules 
#--------------------------------------------------------------------- 
.PHONY: clean directories objects title 

all: directories objects title 

directories: 
@$(MD) $(DIRS) 

clean: 
$(RM) -rf $(OUT_DIR) 

$(OBJS): $(SOURCE_TARGET) 
@$(CC) -c $< -o [email protected] 

$(DEPS): $(SOURCE_TARGET) 
@$(CC) -c -MM $< > $(DEPS) 

-include $(DEPS) 

objects:$(OBJS) $(DEPS) 

title: $(OBJS) 
@$(CC) $< -o [email protected] 

Probé varias opciones y tan muchas veces. Busqué en Google la solución pero no pude encontrar ninguna.

¿Está usando el indicador "-MM" para generar dependencias la opción correcta? Si no, sugiérame la forma correcta de generar las dependencias. Quería generar dependencias automáticamente porque mi proyecto tendrá tantos archivos. Pensé que era la mejor opción que anotar cada dependencia manualmente.

Estos son los errores que estoy recibiendo

g++: stdAfx.d: No such file or directory 
g++: Main.d: No such file or directory 
make: *** No rule to make target `stdAfx.d', needed by `objects'. Stop. 

Gracias de antemano.

+0

¿Qué es "DEPS = $ (OBJS:%. O =%. D)" se supone que está haciendo? ¿Y por qué a veces usas ': =' y algunas veces '='? –

+0

Está creando DEPS con los nombres de los objetos en el directorio de objetos. Solo estoy probando con las opciones '=' y ': = ", pero no sé la diferencia exacta b/w – Jabez

Respuesta

8

Parece que está intentando generar un archivo de dependencia (llamado * .d, según las reglas de su archivo MAKE) para cada archivo .cpp. Esta no es mi comprensión de cómo se usa un archivo de dependencias.

Utilice la opción -M para generar un único archivo de dependencias para su proyecto y luego incluya el archivo de dependencias.

DEPS = $(OUR_DIR)/make.dep 

$(DEPS): $(SOURCE_TARGET) 
    @$(CC) -M $(SOURCE_TARGET) > $(DEPS) 

include $(DEPS) 

edición Su archivo de la dependencia también debe depender de sus cabeceras

$(DEPS): $(SOURCE_TARGET) $(HEADER_TARGET) 
    @$(CC) -M $(SOURCE_TARGET) > $(DEPS) 

donde HEADER_TARGET se define lo mismo que SOURCE_TARGET. De esta forma, cuando se cambia un archivo de cabecera, se reconstruye el archivo de dependencia.

+1

Gracias mcdave, eso es un truco muy bueno. Creo que generar un solo archivo es mejor que generar mucho ... Gracias de nuevo. – Jabez

+1

Solo quiero señalar que '-MM' excluye los encabezados del sistema (más o menos) posiblemente haciendo que la compilación sea más rápida ya que hay menos archivos para 1) verificar 2) proceso para compilar la lista de dependientes. ejemplo, crea foo.cpp con stl incluye y ejecuta 'g ++ -M foo.cpp' para verlo escupir una lista de cerca de 100 dependencias, ninguna de las cuales cambia, y todas tendrán que verificar cada compilación. –

+0

@Robert: Gracias por el consejo: ¡No sabía esto y actualizaré mis makefiles para hacerlos más eficientes! – mcdave

3

Para un principiante, usted está haciendo algunas cosas exóticas. Debe comenzar de manera simple y solo usar código en su Makefile que pueda comprender y confiar al 100%. Incluso en un proyecto grande con cientos de archivos, no perderá mucho tiempo manteniendo el archivo Makefile.

Las variables asignadas con: = se expanden inmediatamente - todos los valores de $ (VAR) se sustituyen en el valor de la variable durante la asignación. Las variables asignadas con = se expanden cuando se usan, por lo que pueden hacer cosas como referirse a variables que aún no están definidas.

La bandera -MM para g ++ generará una línea de dependencia Makefile, p. Ej. foo.o: foo.cc foo.hh, pero nunca lo encontré útil. Tenía un objetivo falso de "dependencia" que generaba un único archivo de dependencia. Su idea de hacer un montón de archivos * .d con esas dependencias de una línea podría funcionar, pero terminará con muchos de esos archivos.

El error que está recibiendo es de g ++, no de make. Es porque está usando $ (DEPS) como si fuera un solo archivo cuando se trata de la lista completa de archivos * .d. Lo que pasa es esta línea:

@$(CC) -c -MM $< > $(DEPS) 

consigue ampliar a:

g++ -c -MM MyFile.cpp > MyFile.d stdAfx.d Main.cpp 

mcdave acaba de publicar el código que he utilizado para generar un archivo de dependencia.Usted puede cambiar el estilo de archivo de dependencia única, o cambiar su orden -MM a esto:

@$(CC) -MM $< > [email protected] 

También es posible que tenga que arreglar la declaración -include porque yo no creo que sea compatible con una lista de archivos para incluir.

+0

Gracias Ken, estoy usando un solo archivo ahora en lugar de tantos archivos múltiples. Gracias diciéndole a diff b/w '=' y ': =', eso seguro me ayuda mucho. – Jabez

Cuestiones relacionadas