Makefiles



  • Hallo, ich hab das mit den MAKEFILES noch nicht so gut verstanden.

    Also ein Makefile habe ich so geschrieben:

    GCC = g++
    
    %: %.cpp
       $(GCC) $< -o $@
    

    Ich habe in meinem Verzeichnis die Datei kehrwert.cpp vorliegen.

    Wenn ich also

    make kehrwert

    eingebe, wird ein Programm kehrwert erstellt.

    Okay, so weit so gut.

    Meine Fragen:

    Kann ich in die Datei makefile jetzt noch viele andere solche

    Ziele: Abhängigkeiten
         Aktion
    

    reinschreiben oder brauch ich jedes Mal eine neue Datei makefile?

    Wie ruft man die dann aber auf?

    Und was hat es mit dem Ziel all auf sich...
    Verstehe ich irgendwie nicht.



  • Du kannst da jede Menge andere Ziele reinschreiben. Es ist meistens auch sinnvoll, das zu tun.

    Ich erläutere mal anhand einer einfachen Makefile:

    target: foo bar
        cat foo bar > target
    
    foo:
        echo Hallo > foo
    
    bar:
        echo Welt > bar
    

    Wenn ich jetzt target bauen will, passiert:

    $ make target
    echo Hallo > foo
    echo Welt > bar
    cat foo bar > target
    

    Und das geht so: "make target" weist make an, das Ziel "target" zu bauen. target hat die Abhängigkeiten foo und bar, also muss make um target zu erstellen, erst foo und bar erstellen (sofern diese nicht schon existieren). Also erstellt make erst foo, dann bar, dann (wenn die Abhängigkeiten erfüllt sind) target mit den angegebenen Kommandos.

    Dabei merkt make, welche Targets schon aktuell sind. Will ich target erneut bauen, so sagt make:

    $ make target
    make: »target« ist bereits aktualisiert.
    

    Sage ich aber

    $ touch foo && make target
    cat foo bar > target
    

    Der Grund dafür ist, dass touch den Zeitstempel von foo erneuert. Jetzt ist foo neuer als target, so dass make glaubt, an foo habe sich etwas geändert, seit target das letzte mal gebaut wurde. Daher ist target nicht auf dem neuesten Stand und muss neu gebaut werden.

    Hätten foo und bar weitere Abhängigkeiten, so würden diese auf die gleiche Weise abgearbeitet.

    Soweit das Grundprinzip -- du beschreibst in einer Makefile einen Abhängigkeitsbaum, den make dann brav abarbeitet, wo es notwendig ist (wo ein benötigtes Ziel nicht existiert oder eine seiner Abhängigkeiten neuer ist als das Ziel). Jetzt gibt es eine Reihe verschiedener Möglichkeiten, Regeln aufzustellen (etwa über Patterns, wie du es hast), implizite Regeln, und man will in der Regel viel mit Variablen arbeiten, um leichter Änderungen vornehmen zu können, aber an der Grundstruktur ändert sich dadurch nichts.

    Ich lass mal einen Link da, hinter dem ein Teil des weiteren Krams erläutert wird. http://www.ijon.de/comp/tutorials/makefile.html



  • Vielen Dank, das hilft mir enorm weiter!

    Der Link hat mir erklärt, was es mit dem target "all" auf sich hat!

    Merci bien, super!



  • LinuxC_newbie schrieb:

    GCC = g++
    
    %: %.cpp
       $(GCC) $< -o $@
    

    Ist jede cpp-Datei ihr eigenständiges Programm? Normalerweise nicht. Es gibt auch schon einige Standardregeln (zumindest bei GNU make). Beispielsweise kann make eigenständig aus cpp-Dateien o-Dateien machen. Dazu verwendet es den Compiler $(CXX) mit Option(en) $(CXXFLAGS):

    CXX = g++
    CXXFLAGS = -Wall -O2
    
    KW_BIN  = kehrwert
    KW_OBJS = kehrwert.o
    
    all: $(KW_BIN)
    
    $(KW_BIN): $(KW_OBJS)
            g++ -o $@ $^
    
    clean:
            rm -f $(KW_BIN) $(KW_OBJS)
    
    .PHONY: all clean
    

    LinuxC_newbie schrieb:

    Kann ich in die Datei makefile jetzt noch viele andere solche
    reinschreiben oder brauch ich jedes Mal eine neue Datei makefile?

    Ja. Nein.

    LinuxC_newbie schrieb:

    Wie ruft man die dann aber auf?

    Mit make <platzhalter für targetname> .

    LinuxC_newbie schrieb:

    Und was hat es mit dem Ziel all auf sich...
    Verstehe ich irgendwie nicht.

    Wenn du größere Projekte baust, wo ein Programm aus mehreren Objekten zusammen gesetzt wird, dann stößt make für dich automatisch all die Kompilier- und Link-vorgänge in der richtigen Reihenfolge an, die benötigt werden. Wenn du Quellcode änderst, muss auch nicht alles neu kompiliert werden. Du musst nur die Abhängigkeiten pflegen, bzw vom Präprozessor generieren lassen. Probier z.B. mal den Präprozessor-Schalter -MMD aus. make kann auch einzelne Files per GCC parallel kompilieren lassen.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Log in to reply