Ich habe ein Projekt, in dem die Verzeichnisstruktur wie folgt ist:
$projectroot
|
+---------------+----------------+
| | |
part1/ part2/ part3/
| | |
+------+-----+ +---+----+ +---+-----+
| | | | | | |
data/ src/ inc/ src/ inc/ src/ inc/
Wie soll ich ein Makefile schreiben, das sich in part / src befindet (oder wo auch immer), das die c / c ++ - Quelldateien teilweise kompilieren / verknüpfen kann? / Src?
Kann ich so etwas wie -I $ projectroot / part1 / src -I $ projectroot / part1 / inc -I $ projectroot / part2 / src ...
Wenn das funktionieren würde, gibt es einen einfacheren Weg, dies zu tun. Ich habe Projekte gesehen, bei denen es in jedem entsprechenden Teil ein Makefile gibt. Ordner. [In diesem Beitrag habe ich das Fragezeichen wie in der Bash-Syntax verwendet]
recursive invocation
, das sehr elegant sein kann.Antworten:
Der traditionelle Weg ist haben
Makefile
in jedem der Unterverzeichnisse (part1
,part2
usw.) so dass Sie sie unabhängig voneinander zu bauen. Haben Sie außerdem einMakefile
im Stammverzeichnis des Projekts, das alles erstellt. Die "Wurzel"Makefile
würde ungefähr so aussehen:Da jede Zeile in einem make-Ziel in einer eigenen Shell ausgeführt wird, müssen Sie sich keine Gedanken über das Durchlaufen des Verzeichnisbaums oder anderer Verzeichnisse machen.
Ich schlage vor, einen Blick auf das GNU-Handbuch 5.7 zu werfen . Es ist sehr hilfreich.
quelle
+$(MAKE) -C part1
usw. sein . Dadurch kann die Jobsteuerung von Make in die Unterverzeichnisse eingearbeitet werden.Wenn Sie Code in einem Unterverzeichnis haben, der von Code in einem anderen Unterverzeichnis abhängig ist, sind Sie wahrscheinlich mit einem einzelnen Makefile auf oberster Ebene besser dran.
Sehen rekursive Make schädlich für die vollen Gründe, aber im Grunde wollen Sie machen die vollständigen Informationen , um es zu entscheiden , ob benötigt oder eine Datei nicht wieder aufgebaut werden muss, und es wird nicht haben, wenn man ihm nur sagen , über ein Drittel dein Projekt.
Der obige Link scheint nicht erreichbar zu sein. Das gleiche Dokument ist hier erreichbar:
quelle
Die VPATH-Option kann nützlich sein, um anzugeben, in welchen Verzeichnissen nach Quellcode gesucht werden soll. Sie benötigen jedoch weiterhin eine Option -I für jeden Include-Pfad. Ein Beispiel:
Dadurch werden die passenden partXapi.cpp-Dateien automatisch in einem der von VPATH angegebenen Verzeichnisse gefunden und kompiliert. Dies ist jedoch nützlicher, wenn Ihr src-Verzeichnis in Unterverzeichnisse unterteilt ist. Für das, was Sie beschreiben, wie andere gesagt haben, sind Sie wahrscheinlich besser dran, wenn Sie für jedes Teil ein Makefile erstellen, insbesondere wenn jedes Teil für sich allein stehen kann.
quelle
VPATH=..
arbeitete für mich!Sie können Ihrem Root-Makefile Regeln hinzufügen, um die erforderlichen CPP-Dateien in anderen Verzeichnissen zu kompilieren. Das folgende Makefile-Beispiel sollte ein guter Anfang sein, um Sie dahin zu bringen, wo Sie sein möchten.
quelle
Wenn die Quellen in vielen Ordnern verteilt sind und es sinnvoll ist, einzelne Makefiles zu haben, ist rekursives Make, wie zuvor vorgeschlagen, ein guter Ansatz, aber für kleinere Projekte finde ich es einfacher, alle Quelldateien im Makefile mit ihrem relativen Pfad aufzulisten zum Makefile wie folgt :
Ich kann dann so einstellen
VPATH
:Dann baue ich die Objekte:
Jetzt ist die Regel einfach:
Und das Erstellen der Ausgabe ist noch einfacher:
Man kann die
VPATH
Erzeugung sogar automatisieren, indem man:Oder die Tatsache verwenden, dass
sort
Duplikate entfernt werden (obwohl dies keine Rolle spielen sollte):quelle
Ich denke, es ist besser darauf hinzuweisen, dass die Verwendung von Make (rekursiv oder nicht) etwas ist, das Sie normalerweise vermeiden möchten, da es im Vergleich zu heutigen Tools schwierig ist, zu lernen, zu warten und zu skalieren.
Es ist ein wunderbares Tool, aber seine direkte Verwendung sollte ab 2010 als veraltet angesehen werden.
Es sei denn, Sie arbeiten in einer speziellen Umgebung, z. B. mit einem Legacy-Projekt usw.
Verwenden Sie eine IDE, CMake oder, wenn Sie hart im Nehmen sind, die Autotools .
(bearbeitet wegen Abstimmungen, ty Honza für den Hinweis)
quelle
RCs Beitrag war SUPER nützlich. Ich habe nie darüber nachgedacht, die Funktion $ (dir $ @) zu verwenden, aber sie hat genau das getan, wofür ich sie brauchte.
Haben Sie in parentDir eine Reihe von Verzeichnissen mit Quelldateien: dirA, dirB, dirC. Verschiedene Dateien hängen von den Objektdateien in anderen Verzeichnissen ab, daher wollte ich in der Lage sein, eine Datei aus einem Verzeichnis heraus zu erstellen und diese Abhängigkeit durch Aufrufen des mit dieser Abhängigkeit verknüpften Makefiles herzustellen.
Im Wesentlichen habe ich ein Makefile in parentDir erstellt, das (unter anderem) eine generische Regel hatte, die der von RC ähnelt:
Jedes Unterverzeichnis enthielt dieses Makefile der oberen Ebene, um diese generische Regel zu erben. Im Makefile jedes Unterverzeichnisses habe ich für jede Datei eine benutzerdefinierte Regel geschrieben, damit ich alles verfolgen kann, von dem jede einzelne Datei abhängt.
Wann immer ich eine Datei erstellen musste, habe ich (im Wesentlichen) diese Regel verwendet, um rekursiv alle Abhängigkeiten zu erstellen. Perfekt!
HINWEIS: Es gibt ein Dienstprogramm namens "makepp", das diese Aufgabe noch intuitiver zu erledigen scheint. Aus Gründen der Portabilität und unabhängig von einem anderen Tool habe ich mich jedoch für diese Aufgabe entschieden.
Hoffe das hilft!
quelle
Rekursive Verwendung von Make
Dies ermöglicht
make
die Aufteilung in Jobs und die Verwendung mehrerer Kernequelle
make -j4
?make
Jobsteuerung überhaupt. Wenn ein separater Make-Prozess ausgeführt wird, unterliegt er nicht der Jobkontrolle.Ich habe nach so etwas gesucht und nach einigen Versuchen und Stürzen erstelle ich mein eigenes Makefile. Ich weiß, dass dies nicht der "idiomatische Weg" ist, aber es ist ein Anfang, Make zu verstehen, und das funktioniert für mich. Vielleicht könnten Sie es in Ihrem Projekt versuchen.
Ich weiß, dass das einfach ist und für einige Leute sind meine Flags falsch, aber wie gesagt, dies ist mein erstes Makefile, das mein Projekt in mehreren Verzeichnissen kompiliert und dann alle miteinander verknüpft, um meinen Bin zu erstellen.
Ich akzeptiere Vorschläge: D.
quelle
Ich schlage vor zu verwenden
autotools
://##
Platzieren Sie generierte Objektdateien (.o) im selben Verzeichnis wie ihre Quelldateien, um Kollisionen zu vermeiden, wenn nicht rekursives make verwendet wird.nur
Makefile.am
mit den anderen ganz einfachen Sachen.Hier ist das Tutorial .
quelle