2008-09-18 12 views

Respuesta

18

La respuesta está en la GCC manual: usar la bandera -MT.

-MT target

cambiar el objetivo de la norma emitida por la generación de dependencia. Por defecto, CPP toma el nombre del archivo de entrada principal, elimina cualquier componente de directorio y cualquier sufijo de archivo, como .c, y agrega el sufijo de objeto habitual de la plataforma. El resultado es el objetivo.

Una opción -MT configurará el destino para que sea exactamente la cadena que especifique. Si desea objetivos múltiples, puede especificarlos como un único argumento en -MT, o utilizar múltiples opciones -MT.

Por ejemplo, podría dar -MT '$(objpfx)foo.o'

$(objpfx)foo.o: foo.c 
+0

'-MT' no está disponible para mi gcc 2.9.5, el invitado debe estar disponible 3.xx arriba – checksum

+2

@checksum: ... no fue [2.9.5] (http://gcc.gnu.org /gcc-2.95/) fue lanzado> hace 14 años? –

+0

Sí, lo descubrí al mantener un código heredado con una plataforma de compilación desactualizada. : | Todavía está usando 2.9.1.57 (se llamó egcs en lugar de gcc) y lo bueno es que tiene una dependencia mínima con 4 archivos solamente y menos de 700k. :) Lo malo es que no tiene soporte '-MT'. :( – checksum

0

Si hay un argumento para gcc para hacer esto, no sé de qué se trata. Terminamos canalizando la salida de dependencia a través de sed para reescribir todas las ocurrencias de .o como $ {OBJDIR} /. O

0

Ok, solo para asegurarme de que tengo la pregunta correcta: supongo que tienes una prueba. c que incluye test.h, y desea generar subdirectorio/test.d (mientras no generación subdirectorio/test.o), donde subdirectorio/test.d contiene

subdir/test.o: test.c test.h 

en lugar de

test.o: test.c test.h 

que es lo que obtienes en este momento. ¿Está bien?

No pude encontrar una manera fácil de hacer exactamente lo que está pidiendo. Sin embargo, mirando a http://www.gnu.org/software/gcc/news/dependencies.html, si desea crear el archivo .d mientras se genera el archivo .o, puede utilizar

gcc $ (INCLUYE) -MMD $ (CFLAGS) $ (SRC) -o $ (sUBDIR)/$ (OBJ)

(Dada SRC = test.c, sUBDIR = subdirectorio, y OBJ = test.o) Esto creará tanto subdirectorio/test.o y subdirectorio/test.d, donde subdir/test.d contiene el resultado deseado como se indica arriba. Espero que ayude.

0
  1. [GNU] se enoja si no coloca la salida en el directorio actual. Lo que realmente debe hacer es ejecutar make desde el directorio de compilación y usar la variable de creación de VPATH para ubicar el código fuente. Si le mientes a un compilador, tarde o temprano se vengará.

  2. Si insiste en generar sus objetos y dependencias en algún otro directorio, necesita usar el argumento -o tal como lo responde Emile.

36

Estoy asumiendo que usted está usando GNU Make y GCC. Primero agregue una variable para contener su lista de archivos de dependencia. Asumiendo que ya tiene uno que muestra todas nuestras fuentes:

SRCS = \ 
     main.c \ 
     foo.c \ 
     stuff/bar.c 

DEPS = $(SRCS:.c=.d) 

a continuación, incluir las dependencias generadas en el makefile:

include $(DEPS) 

a continuación, añadir esta regla patrón:

# automatically generate dependency rules 

%.d : %.c 
     $(CC) $(CCFLAGS) -MF"[email protected]" -MG -MM -MP -MT"[email protected]" -MT"$(<:.c=.o)" "$<" 

# -MF write the generated dependency rule to a file 
# -MG assume missing headers will be generated and don't stop with an error 
# -MM generate dependency rule for prerequisite, skipping system headers 
# -MP add phony target for each header to prevent errors when header is missing 
# -MT add a target to the generated dependency 

"$ @ "es el objetivo (lo que está en el lado izquierdo de:)," $ < "es el requisito previo (lo que está en el lado derecho de:). La expresión "$ (<: .c = .o)" reemplaza la extensión .c con .o.

El truco aquí es generar la regla con dos objetivos sumando -MT dos veces; esto hace que tanto el archivo .o como el archivo .d dependan del archivo fuente y sus encabezados; De esta forma, el archivo de dependencia se regenera automáticamente cada vez que se modifican los archivos .c o .h correspondientes.

Las opciones -MG y -MP evitan que se vuelva loco si falta un archivo de cabecera.

+3

Para mí, en gcc 4.1.2, gmake 3.8.1, si no existe un archivo de encabezado, la receta '$ (CC) $ (CCFLAGS) -MF "$ @" -MG -MM -MP -MT " $ @ "-MT" $ (<:. c = .o) "$ $" bucles infinitos // Eliminar la opción -MP detiene el bucle infinito. –

9

Es posible que como esta versión más breve de la respuesta de Don McCaughey:

SRCS = \ 
    main.c \ 
    foo.c \ 
    stuff/bar.c 

DEPS = $(SRCS:.c=.d)

Añadir -include $(DEPS) nota del - prefijo, que silencia errores si aún no existen los archivos .d.

No hay necesidad de una regla de patrón separada para generar los archivos de dependencia. Simplemente agregue -MD o -MMD a su línea de compilación normal, y los archivos .d se generan al mismo tiempo que se compilan sus archivos fuente. Por ejemplo:

%.o: %.c 
    gcc $(INCLUDE) -MMD -c $< -o [email protected] 

# -MD can be used to generate a dependency output file as a side-effect of the compilation process. 
+2

Por cierto, asegúrese de evitar colocar el "incluir "por encima de tu primer objetivo.Es lógico ubicarlo en la parte inferior del Makefile, porque ese era siempre el lugar tradicional para poner dependencias, ¡cuando tenían que hacerse a mano! –

3

se detallan en la respuesta de DGentry esto ha funcionado bien para mí:

.depend: $(SOURCES) 
    $(CC) $(CFLAGS) -MM $(SOURCES) | sed 's|[a-zA-Z0-9_-]*\.o|$(OBJDIR)/&|' > ./.depend 

Esto también funciona en el caso en el que sólo hay un archivo de depency que contiene las reglas de dependencia para todos los archivos de origen .

Cuestiones relacionadas