makefile - autodependencies für c++



  • Hi,

    Folgendes Problem: Ich verwende ein Makefile für mein Projekt und habe gemerkt, dass Änderungen einer Header Datei keine erneute Kompilierung auslösen.
    Was ist an dem Makefile falsch?

    SRC = util.cpp MyClass.cpp subdir/My2Class.cpp Test.cpp
    OBJ = $(SRC:.cpp=.o)
    
    executable: $(OBJ) depend makefile
    	g++ $(CFLAGS) $(OBJ) -o $@ -lcppunit
    depend: $(SRC) makefile
    	g++ -Wall -MMD -c $<
    clean:
    	rm -f *.o executable.exe /subdir/*.o
    

    Ich bin vertraut mit den Grundlagen von Makefiles, bin aber noch nicht dahinter gekommen wie die autodependencies funktionieren. Ich habe mir folgendes dazu durchgelesen, es war aber zu komplex für diese von mir aus gesehen einfache Aufgabe:
    http://make.paulandlesley.org/autodep.html
    Um da durchzublicken muss ich mir wohl noch sehr viel mehr Zeit nehmen. Die sed/Makefile-Template Mischung machen den Text nicht gerade einfacher.
    Ich meine Visual Studio und Eclipse automatisieren den Vorgang doch auch ohne dass man sich dazu ellenlange Tutorials durchlesen muss und in jeder anderen Programmiersprache die ich verwende braucht man keine Makefiles um solche simplen Abhängigkeiten zu erkennen 😞
    Aber das liegt dann wohl eher daran dass g++ die Abhängigkeiten nicht selbst handelt. Und verstehen wie es funktioniert will ich trotzdem 🙂
    Immerhin sind Makefiles für komplexe Projekte sehr praktisch.

    Danke für eure Hilfe,
    Cream



  • Du musst die erzeugten Dependencies wieder einbinden. Schau dir am besten die Ultimative Makefile an. Die kümmert sich um das ganze.

    Ich würde aber eher CMake benutzen, anstelle die Makefiles per Hand zu schreiben. CMake gibt einem dann Makefiles (oder Projektdateien für diverse IDEs) aus. Alternativ kann man auch ein komplett anderes System wie waf benutzen.



  • Hi,

    Danke für den Tipp. Ich habe versucht das Makefile anzupassen, allerdings stoße ich auf Probleme mit den Unterordnern. Die darin liegenden Dateien werden nicht kompiliert. Außerdem bekomme ich noch Fehlermeldungen zu main:
    main.cpp:6: warning: ISO C++ forbids declaration of main' with no type main hat bei mir aber folgende Signatur: int main( int ac, char **av ) build/main.o:main.cpp:(.text+0x100): multiple definition of_main'
    Es gibt aber nur eine main, sonst hätte ich das Projekt vorher nicht kompilieren können.

    TARGET   := ./program
    CXXFLAGS := -Wall
    CXX      := g++
    LIBS     := -lcppunit
    EXT      := cpp
    BUILDDIR := build
    
    override BUILDDIR := $(strip $(BUILDDIR))
    SOURCES  := $(wildcard *.$(EXT)) $(wildcard $(BUILDDIR)/*.$(EXT))
    OBJECTS  := $(patsubst %.$(EXT), $(BUILDDIR)/%.o, $(SOURCES))
    DEPS     := $(patsubst %.$(EXT), $(BUILDDIR)/%.dep, $(SOURCES))
    
    .PHONY: all
    all: $(TARGET)
    
    $(TARGET): $(OBJECTS) $(DEPS)
    	$(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)
    
    ifneq ($(MAKECMDGOALS), clean)
    -include $(DEPS)
    endif
    
    $(OBJECTS): $(BUILDDIR)/%.o: %.$(EXT) $(BUILDDIR)/%.dep $(BUILDDIR)/.tag
    	$(CXX) $(CXXFLAGS) -c $< -o $@
    
    $(DEPS): $(BUILDDIR)/%.dep: %.$(EXT) $(BUILDDIR)/.tag
    	mkdir -p $(dir $(@))
    	$(CXX) $(CXXFLAGS) -MM $< -MT $@ -MT $(<:.$(EXT)=.o) -o $@
    
    %.tag:
    	mkdir -p $(dir $(@))
    	touch $@
    
    .PHONY: clean
    clean:
    	rm -rf $(BUILDDIR)
    

Anmelden zum Antworten