2009-04-07 6 views
8

Ich lerne Makefiles und ich kann ein einfaches Makefile erstellen. Ich gehe zu verschachtelten Makefiles über. Hier ist meine VerzeichnisstrukturErstellen verschachtelten Makefile

/src 
...makefile 
...main.cpp 
...foo 
......makefile 
......foo.cpp 
......foo.h 

Wenn Wurzel Make-Datei aufgerufen wird, ruft sie die Make-Datei im Verzeichnis foo. Hier sind meine Fragen

  1. Welche Make-Datei sollte ich Code zu schreiben, verwenden für die Verknüpfung aller Objektdateien? Wenn es im Root-Makefile ist, muss ich dort alle Objektdateinamen angeben?
  2. Sind diese verschachtelten Makefiles eine bewährte Methode? Oder ist es gut, nur ein Makefile zu haben, das an der Wurzel ist?

Jede Hilfe wäre großartig!

Antwort

15

Es gibt eine Menge zu sagen für nicht dies zu tun. Lesen Sie Recursive Make Considered Harmful. Auch in PDF form.

Die kurze, kurze Version ist, dass rekursive make effektiv mehrere disjunkte, aber möglicherweise überlappende Abhängigkeitsbäume erstellt und weder einen korrekten noch einen maximal effizienten Build garantieren kann. Das Problem wird schlimmer, wenn Sie hoffen, parallel zu bauen.

Um das Problem zu lösen, ordnen Sie ein einzelnes, nicht-rekursives make an, das einen einzigen übergreifenden Abhängigkeitsbaum erstellt, der es ermöglicht, alle oben genannten Probleme zu lösen.

+1

Wenn nicht, ist eine schlechte Idee, vielleicht sollte eine alternative Lösung als Antwort vorgeschlagen werden. – deadalnix

+1

Ja. Diese Antwort ist in einer Form, die auf der Website nicht mehr akzeptabel ist. Die Änderungen beheben den Mangel nur teilweise, aber es ist etwas. – dmckee

3

Rekursive Marke wird im Allgemeinen als schädlich angesehen.

Wenn Sie wirklich in der Lage sein möchten, "make" in das Root-Verzeichnis einzugeben und alles nur mit POSIX-Makefiles erstellen zu lassen, ist dies der einzige Weg. Verknüpfen Sie in diesem Fall die Teilprojekte in ihrem eigenen Verzeichnis und finalisieren Sie sie in root.

Wenn Sie bereit sind, gmake Syntax zu verwenden, werfen Sie einen Blick auf den Makefiles hier: http://github.com/singpolyma/theveeb-ecosystem

+1

Sie können ein POSIX-Make (nicht GNU) verwenden, um ein nicht-rekursives Build auszuführen, indem Sie es in zwei Schritte aufteilen: 1) alle make.inc-Dateien in allen Unterverzeichnissen verketten; 2) führe das resultierende Makefile aus. Aber die meisten Leute benutzen sowieso GNU make, welches die "include" Direktive hat. –

+0

Ah, das stimmt, ich habe nie von dem Verkettungs-Hack gehört. Ich neige dazu, Include zu verwenden. Normalerweise möchte ich sehr POSIX sein, aber mit Makefiles ist das manchmal etwas haarig wegen der no include Direktive :) – singpolyma

0

Es gibt modernere Build-Systeme wie SCons, dass einen einfachen Syntax haben als viele Fallen von Make zu machen und zu vermeiden. Zum Beispiel scannt SCons die Quelldateien, um Abhängigkeiten zu ermitteln, während man für make Abhängigkeiten manuell angeben muss. Wenn Sie z.B. Fügen Sie einer Implementierungsdatei eine neue # include-Anweisung hinzu make wird diese Implementierungsdatei nicht neu kompilieren, wenn sich die Header-Datei ändert (es sei denn, Sie fügen die neue Abhängigkeit hinzu). SCons erkennt automatisch die neue Abhängigkeit und kompiliert alles was nötig ist.