Frage

Ich bin mit GCC eine Abhängigkeitsdatei zu generieren, aber meine Build-Regeln legen die Ausgabe in einem Unterverzeichnis. Gibt es eine Möglichkeit GCC zu sagen, mein Unterverzeichnis Präfix in der Abhängigkeitsdatei setzt es für mich erzeugt?

gcc $(INCLUDES) -E -MM $(CFLAGS) $(SRC) >>$(DEP)
War es hilfreich?

Lösung

Die Antwort ist in dem GCC Handbuch . verwenden Sie die -MT Fahne

  

-MT target

     

Ändern Sie das Ziel der von der Abhängigkeits Generation emittiert Regel. Standardmäßig nimmt CPP den Namen der Haupteingabedatei löscht alle Verzeichniskomponenten und eine beliebige Datei-Suffix wie .c und fügt die üblichen Objekt-Suffix-Plattform. Das Ergebnis ist das Ziel.

     

Eine -MT Option wird das Ziel gesetzt, genau die Zeichenfolge, die Sie angeben, zu sein. Wenn Sie mehrere Ziele wollen, können Sie sie angeben, als ein einziges Argument -MT oder mehrere -MT Optionen verwenden.

     

Zum Beispiel -MT '$(objpfx)foo.o' geben könnte

$(objpfx)foo.o: foo.c

Andere Tipps

Ich nehme an, Sie verwenden GNU Make und GCC. Zuerst eine Variable fügen Sie Ihre Liste von Abhängigkeitsdateien zu halten. Vorausgesetzt, dass Sie bereits eine haben, dass alle unsere Quellen auflistet:

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

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

Dann sind die erzeugten Abhängigkeiten in der Make-Datei:

include $(DEPS)

Dann dieses Muster Regel hinzuzufügen:

# 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

„$ @“ ist das Ziel (das Ding auf der linken Seite der:), „$ <“ ist die Voraussetzung (die Sache auf der rechten Seite der:). Der Ausdruck "$ (<:. c = .o)" ersetzt die Erweiterung .c mit .o.

hier Der Trick ist, die Regel mit zwei Zielen zu erzeugen, durch Zugabe von -MT zweimal; Dies macht sowohl die .o-Datei und die .d-Datei hängen von der Quelldatei und ihre Header; auf diese Weise die Abhängigkeit Datei wird automatisch neu generiert, wenn einer der entsprechenden .c oder .h Dateien geändert werden.

Die -MG und -MP Optionen halten von freaking out machen, wenn eine Header-Datei fehlt.

Sie können mögen diese briefer Version von Don McCaughey des Antwort :

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

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

Fügen Sie den -include $(DEPS) Präfix - beachten Sie, welche Fehler zum Schweigen bringt, wenn die .d Dateien noch nicht existieren.

Es gibt keine Notwendigkeit für eine separate Musterregel der Abhängigkeitsdateien zu erzeugen. Fügen Sie einfach -MD oder -MMD zu Ihrer normalen Kompilation Linie und die .d Dateien zur gleichen Zeit werden die Quelldateien kompiliert erhalten erzeugt. Zum Beispiel:

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

Detaillierung auf DGentry Antwort , dies funktioniert gut für mich:

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

Das funktioniert auch in dem Fall, in dem es nur eine Abhängigkeitsdatei ist, die die Abhängigkeitsregeln für alle Quelldateien enthalten.

Ok, nur um sicherzustellen, dass ich die Frage richtig verstanden habe ich: Ich nehme an, Sie test.c haben, die test.h enthält, und Sie wollen subdir/test.d erzeugen (während nicht Erzeugung subdir/test.o), wo subdir/test.d enthält

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

statt

test.o: test.c test.h

das ist, was Sie jetzt zu bekommen. Ist das richtig?

war ich nicht in der Lage eine einfache Möglichkeit zu kommen genau das zu tun, was Sie fragen nach. Allerdings Blick auf Dependency-Generation Verbesserungen wenn Sie die .d Datei erstellen möchten, während Sie die .o-Datei generieren, können Sie verwenden:

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

(gegeben SRC=test.c, SUBDIR=subdir und OBJ=test.o.) Dies erzeugt sowohl subdir / test.o und subdir / test.d, wobei die gewünschte Ausgabe subdir/test.d wie oben enthält.

Wenn es ein Argument für GCC, dies zu tun, ich weiß nicht, was es ist. Wir am Ende kochend die Abhängigkeit Ausgabe über sed alle Vorkommen von <blah>.o als ${OBJDIR}/<blah>.o neu zu schreiben.

  1. [GNU] machen wird wütend, wenn Sie die Ausgabe im aktuellen Verzeichnis nicht platzieren. Sie sollten sich wirklich laufen aus dem Build-Verzeichnis machen, und verwenden Sie die VPATH Variable, den Quellcode ausfindig zu machen. Wenn Sie zu einem Compiler liegen, früher oder später wird es seine Rache nehmen.

  2. Wenn Sie darauf bestehen, auf Ihre Objekte und Abhängigkeiten in einem anderen Verzeichnis zu erzeugen, müssen Sie das -o Argument verwenden, wie beantwortet von Emile .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top