Ich stehe gerade vor einem mir großteils unbekannten Projekt, in dem ca. 20 .c-Dateien in einem src-Ordner liegen (d.h. es gibt keine Unterordner für eine übersichtlichere Struktur). Die Makefiles sind aktuell auch auf diese Struktur hin ausgelegt. Ich würde gerne die Möglichkeit schaffen, jede logische Komponente in einen Unterordner zu legen und zwar so, dass das Projekt (schlussendlich wird eine .hex-Datei erzeugt) kompiliert werden kann. Aktuell sieht es so aus: src/main/c/ -----------file_1.c -----------file_2.c -----------... -----------file_n.c So hätte ich es gerne src/main/c/ ----------Komponente_1/ ----------------------file_1.c ----------------------file_2.c ----------------------file_1.h ----------------------file_2.h ----------Komponente_2/ ----------------------... ----------... ----------Komponente_n Ich hab mich nun etwas in Make eingelesen (hab davon ehrlich gesagt nicht viel Ahnung) und habe herausgefunden, dass es im Prinzip zwei Lösungswegen gibt: 1. Ein Makefile im Ordner src (bzw. src/main/c), dass sich alle .c-Dateien zusammensucht und dann das .hex-File erstellt 2. Ein Makefile im Ordner src (bzw. src/main/c) und für jeden Unterordner mit Source-Dateien (Komponente_1 etc.) ein extra Makefile, dass die enthaltenen .c-Dateien zu .o-Dateien macht. Das "Haupt"-Makefile im src-Ordner erzeugt dann aus den .o-Dateien der Unterordner das .hex-File (rekursiv). Mein Problem ist nur, dass ich dazu keine einsteigerfreundliche Anleitung finde. Eine zusätzliche Hürde ist, dass die verschiedenen Header-Dateien auch andere Header-Dateien inkludieren und ich nicht weiß, wie und ob man diese Abhängigkeiten untereinander überhaupt bewältigen kann? Für erste Tipps wäre ich sehr, sehr dankbar. Grüße P.S. Das Ganze wird mit dem avr-gcc kompiliert, weiß nicht ob diese Info nützlich ist.
:
Bearbeitet durch User
http://aegis.sourceforge.net/auug97.pdf Dieses PDF ist zwar auf englisch und über 20 Jahre alt, aber hat m.M.n einen sehr guten Ansatz wie man größere Projekte mit make handeln kann. Grundsätzlich: - ein zentrales Makefile mit allem was man zum kompilieren braucht, ausser die Liste an Source-Dateien - in jedem Unterverzeichnis ein "node.mk" o.Ä. was im zentralen Makefile eingebunden wird und nur die Source-Dateien im jeweiligen Verzeichnis auflistet.
Bei so wenigen Dateien reicht ein makefile, die Aufteilung auf mehrere ist da eher eine akademische Übung. Und ganz generell wäre eine IDE, die automatisch makefiles erstellt, die bequemste Lösung. Oliver
:
Bearbeitet durch User
Ich habe für meine eigenen Projekte eine Art Framework entwickelt, das so ähnlich funktioniert. Vielleicht ist es ja für deine Anwendung brauchbar bzw. ohne grösseren Aufwand anzupassen: https://github.com/sourcebox/cpmk Es arbeitet nicht generell mit rekursiven Makefiles, sondern inkludiert optional pro Komponente zwei Makefiles. Damit kann man z.B. Compilerflags pro Komponente setzen.
Max M. schrieb: > und habe herausgefunden, dass es im Prinzip zwei > Lösungswegen gibt ... da gibt es noch einen dritten, sehr einfachen Lösungsweg, der manchmal prima ist (für relativ simple, überschaubare Projekte) und manchmal überfordert: das einfache Setzen der VPATH-Variable kann u.U. deine Wünsche schon erfüllen.
Oliver S. schrieb: > Und ganz generell wäre eine IDE, die automatisch makefiles erstellt, die > bequemste Lösung. Ist mir auch gerade aufgefallen als ich versucht habe, die Projektstruktur an meinem privaten PC nachzubauen. Ich werd morgen mal versuchen, das Projekt mit Atmel Studio und dem auto-generierten Makefile zu kompilieren.
Hi Von IDE generierten Dateien halte ich wenig bis nichts. Man findet sich an eine IDE. Ich würde entweder zu selbst geklöppelten makefiles + vom GCC erzeugten Dependencydateien (hoher Lerneffekt) oder aber cmake als make/Ninja Generator raten. Matthias
Μαtthias W. schrieb: > Von IDE generierten Dateien halte ich wenig bis nichts. Macht ja nix. Jeder Jeck is anders. Man findet sich > Ich würde entweder zu selbst geklöppelten makefiles + vom > GCC erzeugten Dependencydateien (hoher Lerneffekt) Programmierst du schon, oder klöppelst du noch? Oliver
:
Bearbeitet durch User
Oliver S. schrieb: > Μαtthias W. schrieb: >> Von IDE generierten Dateien halte ich wenig bis nichts. > Macht ja nix. Jeder Jeck is anders. Foren sind doch dazu da Meinungen auszutauschen oder? > Man findet sich >> Ich würde entweder zu selbst geklöppelten makefiles + vom >> GCC erzeugten Dependencydateien (hoher Lerneffekt) > > Programmierst du schon, oder klöppelst du noch? Ich hab mal lang an einem recht komplexe Konstrukt aus makefiles gebastelt. Dafür war dann das Anlegen eines neuen Projekts nur noch das anlegen eines Verzeichnis. Damit könnte dann für verschiedene Architekturen (x86, x64, Cortex-M, ARM9, Cortex-A) und Betriebssysteme (Baremetal, Windows, Linux, Free-RTOS) gebaut werden mit nur einem Befehl. Inkl. Unittests, Codecoverage usw. Wüßte nicht wie man das in einer einzigen IDE abbilden sollte. Allerdings würde ich dafür auch bezahlt :-)
Ein makefile pro Ordner wäre für mich als Liebhaber von Hierarchien der absolute Horror. Ich seh da auch keinen Vorteil weil man sich ja via shell find eh alle Sourcen aus den Unterordner saugen kann?
1 | SRC_DIRS += ./driver/newlib |
2 | SRC_DIRS += ./src/target |
3 | # usw. usf.
|
4 | |
5 | SRCS := $(shell find $(SRC_DIRS) -name *asm -or -name *.s -or -name *.S -or -name *.c -or -name *.cc -or -name *.cpp) |
Headerabhängigkeiten können durch die vom Compiler generierten .d files aufgelöst werden:
1 | # Include all dependency files (.d)
|
2 | DEPS := $(OBJS:.o=.d) |
3 | |
4 | # Create include directories from dependency files
|
5 | INC_DIRS += $(shell find $(SRC_DIRS) -type d) |
:
Bearbeitet durch User
Vincent H. schrieb: > Ein makefile pro Ordner wäre für mich als Liebhaber von Hierarchien der > absolute Horror. Ich seh da auch keinen Vorteil weil man sich ja via > shell find eh alle Sourcen aus den Unterordner saugen kann? Es gibt viele verschiedene Gründe und Strategien, die mehrere Makefiles rechtfertigen. Ich mache das manchmal, wenn ich verschiedene Teile ganz anders bauen muss. z.B. bei diesem Monster hier, mit dem ich devuan images fürs librem5 baue: https://github.com/Daniel-Abrecht/librem5-image-builder Da hab ich erstmal eine Datei die ich in allen Makefiles einbinde, und allgemeines wie z.B. git repos clonen, resetten und aktualisieren, repo urls und andere Einstellungen ändern, etc. enthält: https://github.com/Daniel-Abrecht/librem5-image-builder/blob/master/src/make-helper-functions.mk Das Hauptmakefile, dass aus allen Komponenten die Images baut: https://github.com/Daniel-Abrecht/librem5-image-builder/blob/master/makefile Das Hauptmakefile führt dann noch die Makefiles zum bauen der Komponenten aus. Beim Kernel ist das einfach repo clonen, config file anlegen, und dann das Makefile des Kernelrepos mit den entsprechenden Parametern fürs crosscompiling ausführen: https://github.com/Daniel-Abrecht/librem5-image-builder/tree/master/kernel Beim u-boot ist dass dann viel Komplizierter, da muss ich noch Firmware und weitere Projekte holen, zeug rumkopieren sonstige Tools aufrufen, usw. https://github.com/Daniel-Abrecht/librem5-image-builder/blob/master/uboot/makefile Und für andere debian Packete, die ich cross compiliert noch so brauche, hab ich ein allgemeines Makefile, wo ich erst noch das Buildenvironment usw. generieren lassen muss: https://github.com/Daniel-Abrecht/librem5-image-builder/blob/master/chroot-build-helper/makefile Die verschiedenen dinge müssen derart unterschiedlich gebaut werden, nur ein Makefile ist da einfach nicht sinnvoll. Was komplett anderes war das ding: https://github.com/Daniel-Abrecht/dpaparser Da hatte ich parser code von nem Template generieren lassen, durch den C preprozessor. Brauchte sowas dann noch bei nem anderen Projekt, also ausgelagert. Das ist ein Programm oder Script, bei dem es sich um ein Makefile handelt. Und dann gibt es noch Situationen wie beim Linux Kernel, wo man auswählen kann, welche Teile man wie bauen will. Das nutzt dort die schon erwähnte Methode, die Sourcen der Komponenten in dessen Verzeichnis aufzulisten, plus noch Abhängigkeitskram. Projekte sind nicht immer nur ein simples allen Quellcode durch den Compiler jagen und fertig.
DPA schrieb: > Es gibt viele verschiedene Gründe und Strategien, die mehrere Makefiles > rechtfertigen. > > etc. Richtig, hab ich ja auch nie angezweifelt. Das simple Zusammensuchen von Source-Datein aus Unterordner ist aber imho eben kein so ein Grund.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.