Pregunta

Estoy usando GCC para generar un archivo de dependencia, pero mi compilación de normas de la salida en un subdirectorio.Hay una manera de decirle a GCC para poner mi subdirectorio prefijo en el archivo de dependencia que genera para mí?

gcc $(INCLUDES) -E -MM $(CFLAGS) $(SRC) >>$(DEP)
¿Fue útil?

Solución

La respuesta está en el Manual de GCC:el uso de la -MT de la bandera.

-MT target

Cambiar el objetivo de la norma emitida por la dependencia de la generación.Por defecto CPP toma el nombre de la entrada principal del archivo, elimina los componentes del directorio y cualquier sufijo de archivo, tales como .c, y lo anexa de la plataforma de objetos habitual sufijo.El resultado es el destino.

Un -MT opción de establecer el objetivo a ser exactamente la cadena especificada.Si desea que varios objetivos, se pueden especificar como un solo argumento para -MT, o el uso de múltiples -MT opciones.

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

$(objpfx)foo.o: foo.c

Otros consejos

Estoy asumiendo que usted está utilizando GNU Make y GCC.En primer lugar añadir una variable para almacenar la lista de archivos de dependencia.Asumiendo que ya tiene uno que enumera todas nuestras fuentes:

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

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

A continuación, incluir genera dependencias en el archivo makefile:

include $(DEPS)

A continuación, agregue este patrón de regla:

# automatically generate dependency rules

%.d : %.c
        $(CC) $(CCFLAGS) -MF"$@" -MG -MM -MP -MT"$@" -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 destino (la cosa en el lado izquierdo de la :), "$<"es el requisito previo (la cosa en el lado derecho de la :).La expresión "$(<:.c=.o)" sustituye a la .c extensión .o.

El truco aquí es generar la regla, con dos objetivos mediante la adición de -MT dos veces;esto hace que tanto el .oh, y el archivo .d archivo dependen del archivo de origen y sus cabeceras;de esa manera la dependencia de archivo se regenera automáticamente cuando se produzca alguna de las correspondientes .c o .h archivos se ha cambiado.

El MG y -MP opciones de mantener hacen de los estribos si un archivo de encabezado de la falta.

Usted puede tener gusto de esta breve versión de No McCaughey la respuesta:

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

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

Agregar -include $(DEPS) nota la - prefijo, que silencia a los errores, si los .d archivos aún no existen.

No hay necesidad de otro patrón de la regla para generar los archivos de dependencia.Simplemente añadir -MD o -MMD para su normal línea de compilación, y el .d los archivos se genera al mismo tiempo los archivos de código fuente se compila.Por ejemplo:

%.o: %.c
     gcc $(INCLUDE) -MMD -c $< -o $@

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

Que se detalla en DGentry la respuesta, 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 de que sólo hay una dependencia del archivo que contiene la dependencia de reglas para todos los archivos de origen.

Ok, sólo para asegurarse de que tenemos la pregunta:Estoy asumiendo que usted tiene test.c que incluye test.h, y desea generar subdir/test.d (mientras no la generación de subdir/test.o) donde subdir/test.d contiene

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

en lugar de

test.o: test.c test.h

que es lo que puedes conseguir ahora mismo.Es ese derecho?

Yo no era capaz de venir para arriba con una manera fácil de hacer exactamente lo que usted está pidiendo.Sin embargo, mirando La Dependencia De La Generación De Mejoras, si desea crear la .d archivo mientras generar el .o archivo, puede utilizar:

gcc $(INCLUDES) -MMD $(CFLAGS) $(SRC) -o $(SUBDIR)/$(OBJ)

(Dado SRC=test.c, SUBDIR=subdir, y OBJ=test.o.) Esto va a crear tanto subdir/prueba.o y subdir/prueba.d, donde subdir/test.d contiene la salida deseada, como se indicó anteriormente.

Si hay un argumento a GCC para hacer esto, no sé lo que es.Terminamos la tubería de la dependencia de salida a través de sed para volver a escribir todas las apariciones de <blah>.o como ${OBJDIR}/<blah>.o.

  1. [GNU] que se enoja si no el lugar de salida en el directorio actual.Usted realmente debe hacer ejecutar desde el directorio de construcción, y el uso de la VPATH hacer variable para localizar el código fuente.Si usted se acuesta a un compilador, tarde o temprano se va a tomar su venganza.

  2. Si usted insiste en la generación de sus objetos y dependencias en cualquier otro directorio, usted necesita usar el -o el argumento, como respondida por Emile.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top