Frage an makefile, c++ – makefile automatische Erkennung von src-Dateien und Generierung von Abhängigkeiten

2

Ich habe das folgende Setup für mein C ++ - Projekt:

im src-ordner gibt es * .cpp und entsprechende * .h dateien und in den obj-ordnern möchte ich meine .o-dateien haben.

Bisher ist das Kompilieren und Verknüpfen nicht das Problem. Aber jetzt habe ich zu viele .cpp- und .h-Dateien, um sie manuell in das Makefile zu kopieren. Also habe ich beschlossen, diese kleine Anweisung in das Makefile zu schreiben:

<code>collect_sources:
@echo "collecting source files";
@echo "SRCS = \\" > sources;
@for file in ./src/*.cpp; \
do \
    echo "$$file \\" >> sources; \
done
</code>

Ich auch

<code>-include sources
</code>

am Anfang des Makefiles

Die resultierende Dateisources sieht gut aus, obwohl es einen Backslash in der letzten Zeile gibt, den ich nicht mag. Aber afaik sollte es auch schädlich sein.

Ich muss jetzt auch automatisch Abhängigkeiten aufbauen. In meiner letzten Version, in der ich die * .cpp-Dateien als definiert habeSRCS direkt im Makefile war der folgende Code gut:

<code>$(SRCDIR)/%.cpp:
  @$(CXX) $(DEPFLAGS) -MT \
  "$(subst $(SRCDIR),$(OBJDIR),$(subst $(EXT_SRC),$(EXT_OBJ),$$file))" \
  $(addprefix ,$$file) >> $(DEP);
clear_dependencies:
    echo "" > $(DEP);

depend: clear_dependencies $(SRCS)
</code>

Aber mit dem Einbeziehen dersources-file, erreicht nie den oberen Codeblock.

Hier sind die oben im Makefile definierten Konstanten:

<code>CXX = g++
CXXFLAGS = -Wall \
       -Wextra \
       -Wuninitialized \
       -Wmissing-declarations \
       -pedantic \
       -O3 \
       -p -g -pg
LDFLAGS =  -p -g -pg
DEPFLAGS = -MM

SRCDIR  = ./src
OBJDIR  = ./obj

TARGET = ./bin/my_funky_function_which_is_not_the_real_name

-include sources

OBJSTMP =   $(SRCS:.cpp=.o)
OBJS        =   $(OBJSTMP:$(SRCDIR)=$(OBJDIR))
DEP = depend.main
EXT_SRC =   .cpp
EXT_OBJ =   .o
</code>

Was vermisse ich? Ist mein Ansatz gültig / machbar?

Es gibt einen einfachen Fehler und viele mögliche Verbesserungen. Wie weit willst du gehen? Beta
Nebenbei bemerkt: Bitte schlagen Sie kein Tool vor, das dies bereits tut. Ich möchte das wirklich verstehen und die volle Kontrolle darüber haben, was passiert. stefan
Schritt für Schritt zum absoluten Optimum ;-) stefan

Deine Antwort

1   die antwort
7

Gut, Sie haben danach gefragt.

1: Ihrecollect_sources:... include sources ist herrlich Rube Goldberg Hackery. Mach einfach folgendes:

<code>SRCS = $(wildcard ./src/*.cpp)
</code>

Und wenn Sie es per Auge bestätigen möchten, können Sie dies tun:

<code>$(info $(SRCS))
</code>

2:

<code>clear_dependencies:
    echo "" > $(DEP);
</code>

Lassen Sie uns dies aus Gründen der Ästhetik beheben.

<code>clear_dependencies:
    $(RM) $(DEP);
</code>

3:

<code>$(SRCDIR)/%.cpp:
    @$(CXX) $(DEPFLAGS) -MT \
  "$(subst $(SRCDIR),$(OBJDIR),$(subst $(EXT_SRC),$(EXT_OBJ),$$file))" \
  $(addprefix ,$$file) >> $(DEP);
</code>

Dies wird einige Arbeit in Anspruch nehmen. Zunächst das unmittelbare Problem: Das Ziel ist eine echte Datei, die existiert, und die Regel hat keine Voraussetzungen. Daher wird die Regel nicht ausgeführt (ich habe keine Ahnung, warum es in einer früheren Version für Sie funktioniert hat, vielleicht war etwas anderes anders). Als vorübergehende Korrektur schlage ich vor, auf eine statische Musterregel und PHONY-Ziele zu wechseln:

<code>.PHONY:$(SRCS)
$(SRCS) : $(SRCDIR)/%.cpp:
    @$(CXX) $(DEPFLAGS) -MT \
   ...
</code>

Sehen Sie, ob das alles funktioniert, dann können wir die großen Dinge angehen.

Nein, es ist ein Nebeneffekt, die Quellen zu PHONY-Zielen zu machen. Beta
Cool. In ein paar Stunden habe ich Zeit, um mehr hinzuzufügen. Beta
Zunächst einmal vielen Dank für Ihre Antwort. Ich verstehe nicht, was Sie mit "das Ziel ist eine echte Datei, die existiert" meinen. Sie haben Recht, dass es ursprünglich nicht dieser Code war. anstelle von $ Datei war es etwas mit einem @. stefan
Du hast absolut recht. und mit Ihrem "PHONY" -Vorschlag und "$ @" funktioniert es gut :) stefan

Verwandte Fragen