Digamos que tengo un archivo MAKE con la regla
%.o: %.c
gcc -Wall -Iinclude ...
Quiero que * .o se reconstruya cada vez que cambie un archivo de encabezado. En lugar de elaborar una lista de dependencias, siempre que cualquier archivo de encabezado en/include
cambie , todos los objetos del directorio deben reconstruirse.
No puedo pensar en una buena manera de cambiar la regla para adaptarse a esto, estoy abierto a sugerencias. Puntos de bonificación si la lista de encabezados no tiene que estar codificada
dependencies
makefile
header-files
Miguel
fuente
fuente
Respuestas:
Si está utilizando un compilador GNU, el compilador puede ensamblar una lista de dependencias por usted. Fragmento de Makefile:
o
donde
SRCS
es una variable que apunta a su lista completa de archivos fuente.También está la herramienta
makedepend
, pero nunca me gustó tanto comogcc -MM
fuente
depend
ejecutar solo cuando los archivos de origen han cambiado? Parece que se ejecuta siempre independientemente ...build/file.o
?La mayoría de las respuestas son sorprendentemente complicadas o erróneas. Sin embargo, se han publicado ejemplos simples y sólidos en otros lugares [ revisión de código ]. Es cierto que las opciones proporcionadas por el preprocesador gnu son un poco confusas. Sin embargo, la eliminación de todos los directorios del destino de compilación con
-MM
está documentada y no es un error [ gpp ]:La
-MMD
opción (algo más nueva) es probablemente lo que desea. Para completar, un ejemplo de un archivo MAKE que admite varios directorios src y directorios de compilación con algunos comentarios. Para una versión simple sin directorios de compilación, vea [ codereview ].Este método funciona porque si hay varias líneas de dependencia para un solo objetivo, las dependencias simplemente se unen, por ejemplo:
es equivalente a:
como se menciona en: Makefile múltiples líneas de dependencia para un solo objetivo?
fuente
CPP
debe leerseCPPS
a.cpp
,b.cpp
) en./src/
, ¿no haría esa sustitución$(OBJ)=./build/src/a.o ./build/src/b.o
?Como publiqué aquí, gcc puede crear dependencias y compilar al mismo tiempo:
El parámetro '-MF' especifica un archivo para almacenar las dependencias.
El guión al comienzo de '-include' le dice a Make que continúe cuando el archivo .d no existe (por ejemplo, en la primera compilación).
Tenga en cuenta que parece haber un error en gcc con respecto a la opción -o. Si configura el nombre de archivo del objeto para que diga obj / _file__c.o, entonces el archivo .d generado aún contendrá el archivo .o, no obj / _file__c.o.
fuente
man gcc
dice-MM
implica-E
, que "se detiene después del preprocesamiento". Necesita en su-MMD
lugar: stackoverflow.com/a/30142139/895245¿Qué tal algo como:
También puede usar los comodines directamente, pero suelo encontrar que los necesito en más de un lugar.
Tenga en cuenta que esto solo funciona bien en proyectos pequeños, ya que supone que cada archivo de objeto depende de cada archivo de encabezado.
fuente
make clean all
todo el tiempo.gcc
línea no se ejecuta en absoluto, pero en su%o: %.c
lugar se ejecuta la regla incorporada ( regla).La solución de Martin anterior funciona muy bien, pero no maneja archivos .o que residen en subdirectorios. Godric señala que la bandera -MT se encarga de ese problema, pero simultáneamente evita que el archivo .o se escriba correctamente. Lo siguiente se encargará de ambos problemas:
fuente
Esto hará el trabajo bien, e incluso manejará los subdirectorios que se especifican:
lo probé con gcc 4.8.3
fuente
Aquí hay dos líneas:
Esto funciona con la receta de creación predeterminada, siempre que tenga una lista de todos sus archivos de objeto en formato
OBJS
.fuente
Prefiero esta solución, sobre la respuesta aceptada por Michael Williamson, detecta cambios en las fuentes + archivos en línea, luego en las fuentes + encabezados y, finalmente, solo en las fuentes. La ventaja aquí es que no se vuelve a compilar toda la biblioteca si solo se realizan unos pocos cambios. No es una gran consideración para un proyecto con un par de archivos, pero si tiene 10 o 100 fuentes, notará la diferencia.
fuente
Lo siguiente funciona para mí:
fuente
Una versión ligeramente modificada de la respuesta de Sophie que permite enviar los archivos * .d a una carpeta diferente (solo pegaré la parte interesante que genera los archivos de dependencia):
Tenga en cuenta que el parámetro
se utiliza para asegurar que los destinos (es decir, los nombres de los archivos de objetos) en los archivos * .d generados contienen la ruta completa a los archivos * .o y no solo el nombre del archivo.
No sé por qué NO se necesita este parámetro cuando se usa -MMD en combinación con -c (como en la versión de Sophie ). En esta combinación, parece escribir la ruta completa de los archivos * .o en los archivos * .d. Sin esta combinación, -MMD también escribe solo los nombres de archivo puros sin ningún componente de directorio en los archivos * .d. Quizás alguien sepa por qué -MMD escribe la ruta completa cuando se combina con -c. No he encontrado ninguna pista en la página de manual de g ++.
fuente