2012-10-12 138 views
10

Estoy usando gmake y gcc -MM para rastrear las dependencias de encabezado, siguiendo the manual. El mecanismo se basa en una directiva makefile include para importar las dependencias calculadas.GNU make: objetivo limpio depende de incluye

Como los archivos .d están incluidos en el archivo MAKE, deben existir para cualquier objetivo que se realice, incluido clean. Entonces, antes de clean puede hacer lo correcto, las dependencias deben ser generadas, y si no se puede construir, entonces clean acaba de hacer más lío.

Además de clean, quiere hacer todas las dependencias antes de construir cualquier objetivo.

Además, si se cambia cualquier archivo para incluir un archivo inexistente, la resolución de la dependencia se rompe y nada se compilará.

Si se elimina un encabezado, los archivos de dependencia existentes todavía lo nombran como destino, y nada se compilará hasta que se eliminen los archivos de dependencia ofensivos ... lo que no se puede hacer con clean.

Reemplazar el patrón de sustitución del include con un comodín para incluir todos los archivos de dependencia preexistentes resuelve algunos de los problemas, pero aún no puede eliminar una dependencia defectuosa y los archivos de dependencia obsoletos nunca se eliminan. ¿Hay una mejor solución? ¿El ejemplo del manual realmente está destinado para uso real?

Respuesta

15

Simplemente no proporcionan una regla para generar .d archivos. Una buena explicación de por qué no es tan bueno (incluido su caso también) está disponible en "Advanced Auto-Dependency Generation" de Paul Smith - un mantenedor de GNU Make.

En pocas palabras, el siguiente patrón me da buenos resultados para todos los casos:

CPPFLAGS += -MMD -MP 

%.o: %.c 
    $(CC) $(CPPFLAGS) $(CFLAGS) -o [email protected] -c $< 

-include $(OBJS:.o=.d) 

Véase también mis anteriores respuestas relacionadas:

+0

@Potatoswatter, no. En este caso, la generación de archivos .d se combina con la compilación real, GCC realiza estos pasos en una sola invocación. –

+0

Lo siento, no debería haber hablado antes de leer un poco más. Parece que '-MP' resuelve el problema restante después de lo resuelto. Pero prefiero mantener los objetos en otro directorio de las fuentes, y es posible que desee un mayor procesamiento de los archivos de dependencia para admitir encabezados precompilados. – Potatoswatter

+0

@Potatoswatter, nunca antes había usado PCH, sin embargo, dividir directorios de objetos y fuentes no es un gran problema. Simplemente prefija el objetivo y el requisito previo con las rutas: '$ (OBJ_DIR) /%. O: $ (SRC_DIR) /% .c'. Los archivos de dependencia se ubicarán cerca de los archivos del objeto, en '$ (OBJ_DIR)'. –

2

Mi patrón habitual parece

all: target 
target: .depends 

## [snip build rules] 

.depends: 
    gcc -MM $(CPPFLAGS) .... > [email protected] 

-include .depends 

Nota -include en lugar de include. Básicamente, se incluye de forma condicional: es decir, si y sólo si existe el archivo

Ver documentación: http://www.gnu.org/software/make/manual/make.html#Include

+0

1: añadiendo el signo menos fija el problema inmediato.Gracias, ahora estoy apuntando en la dirección correcta ... – Potatoswatter

+4

Es poco óptimo e innecesario tener una regla para generar dependencias en estos días. Las dependencias se generan mejor como un subproducto de la compilación. Para la primera compilación las dependencias son innecesarias ya que cada fuente necesita ser construida. Solo para construcciones posteriores se necesitan dependencias y han sido producidas por una compilación anterior. –

+0

@MaximYegorushkin aprendo todos los días. Bonito. (También leo las otras respuestas :)) – sehe

Cuestiones relacionadas