Domanda

Sto utilizzando GCC per generare un file di dipendenze, ma le mie regole di creazione inseriscono l'output in una sottodirectory.C'è un modo per dire a GCC di inserire il prefisso della mia sottodirectory nel file di dipendenza che genera per me?

gcc $(INCLUDES) -E -MM $(CFLAGS) $(SRC) >>$(DEP)
È stato utile?

Soluzione

La risposta è nel Manuale del GCC:Usa il -MT bandiera.

-MT target

Modificare l'obiettivo della regola emessa dalla generazione delle dipendenze.Per impostazione predefinita, CPP prende il nome del file di input principale, elimina tutti i componenti della directory e qualsiasi suffisso di file come .c, e aggiunge il consueto suffisso oggetto della piattaforma.Il risultato è l'obiettivo.

UN -MT l'opzione imposterà la destinazione in modo che sia esattamente la stringa specificata.Se desideri più target, puoi specificarli come un unico argomento -MT, o utilizzarne più di uno -MT opzioni.

Per esempio, -MT '$(objpfx)foo.o' potrebbe dare

$(objpfx)foo.o: foo.c

Altri suggerimenti

Presumo che tu stia utilizzando GNU Make e GCC.Per prima cosa aggiungi una variabile per contenere l'elenco dei file di dipendenza.Supponendo che tu ne abbia già uno che elenca tutte le nostre fonti:

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

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

Quindi includi le dipendenze generate nel makefile:

include $(DEPS)

Quindi aggiungi questa regola del modello:

# 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

"$@" è il target (la cosa sul lato sinistro di :), "$<" è il prerequisito (l'oggetto sul lato destro di:).L'espressione "$(<:.c=.o)" sostituisce l'estensione .c con .o.

Il trucco qui è generare la regola con due target aggiungendo -MT due volte;questo fa sì che sia il file .o che il file .d dipendano dal file sorgente e dalle sue intestazioni;in questo modo il file delle dipendenze viene rigenerato automaticamente ogni volta che uno dei file .c o .h corrispondenti viene modificato.

Le opzioni -MG e -MP impediscono a make di impazzire se manca un file di intestazione.

Potrebbe piacerti questa versione più breve di La risposta di Don McCaughey:

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

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

Aggiungere -include $(DEPS) notare la - prefisso, che silenzia gli errori se il file .d i file non esistono ancora.

Non è necessaria una regola di modello separata per generare i file di dipendenza.Aggiungi semplicemente -MD O -MMD alla normale riga di compilazione e il .d i file vengono generati contemporaneamente alla compilazione dei file sorgente.Per esempio:

%.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.

Dettagli su La risposta di DGentry, questo ha funzionato bene per me:

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

Funziona anche nel caso in cui sia presente un solo file di dipendenza che contiene le regole di dipendenza per tutti i file di origine.

Ok, solo per essere sicuro di aver risposto correttamente alla domanda:Presumo di sì test.c che include test.h, e vuoi generare subdir/test.d (Mentre non generando subdir/test.o) Dove subdir/test.d contiene

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

piuttosto che

test.o: test.c test.h

che è quello che ottieni adesso.È giusto?

Non sono riuscito a trovare un modo semplice per fare esattamente quello che stai chiedendo.Tuttavia, guardando Miglioramenti alla generazione di dipendenze, se vuoi creare il file .d file mentre generi il file .o, puoi utilizzare:

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

(Dato SRC=test.c, SUBDIR=subdir, E OBJ=test.o.) Questo creerà sia subdir/test.o che subdir/test.d, dove subdir/test.d contiene l'output desiderato come sopra.

Se c’è un argomento a favore del GCC per fare questo, non so quale sia.Finiamo per convogliare l'output delle dipendenze sed per riscrivere tutte le occorrenze di <blah>.o COME ${OBJDIR}/<blah>.o.

  1. [GNU] make si arrabbia se non inserisci l'output nella directory corrente.Dovresti davvero eseguire make dalla directory build e utilizzare la variabile make VPATH per individuare il codice sorgente.Se menti a un compilatore, prima o poi si vendicherà.

  2. Se insisti nel generare i tuoi oggetti e le tue dipendenze in qualche altra directory, devi utilizzare il file -o argomento, come risponde Emilio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top