2009-08-07 13 views
5

ich make verwenden möchte einen modularen Aufbau in Kombination zu bekommen mit continuous integration, automatischen Unit-Tests und Multi-Plattform baut. Ähnliche Konfigurationen sind in Java und .NET üblich, aber es fällt mir schwer, dies für make und C/C++ zusammenzustellen. Wie kann es erreicht werden?perfekte Make-Datei

Meine Anforderungen:

  • schnell zu bauen; nichtrekursiven make (Stapelüberlauf Frage What is your experience with non-recursive make?)
  • modulares System (das heißt, ein minimalen Abhängigkeiten, Make-Datei im Unterverzeichnis mit Komponenten)
  • mehr Plattformen (typischerweise PC für Komponententests, eingebettet Ziel für Systemintegration/release)
  • vollständige Abhängigkeit
  • Fähigkeit Prüfung auszuführen (automatische) -Einheit Tests (Agile Engineering)
  • Haken in kontinuierliche Integrationssystem
  • leicht
  • zu verwenden

Ich habe mit non-rec make gestartet. Ich finde es immer noch großartig, um anzufangen.

Einschränkungen bisher:

  • keine Integration von Unit-Tests
  • Inkompatibilität von Windows-basierten ARM-Compiler mit Cygwin Pfaden
  • Unverträglichkeit von Make-Datei mit dem Windows \ Pfaden
  • vorwärts Abhängigkeiten

Meine Struktur wie folgt aussieht:

project_root 
     /algorithm 
       /src 
        /algo1.c 
        /algo2.c 
       /unit_test 
        /algo1_test.c 
        /algo2_test.c 
       /out 
        algo1_test.exe 
        algo1_test.xml 
        algo2_test.exe 
        algo2_test.xml 
      headers.h 
     /embunit 
     /harnass 
    makefile 
    Rules.top 

Ich möchte die Dinge einfach zu halten; hier hängen die Komponententests (algo1_test.exe) sowohl von der "Algorithmus" -Komponente (ok) als auch von dem Komponententest-Framework ab (die zum Zeitpunkt des Aufbaus bekannt sein können oder nicht). Das Verschieben der Erstellungsregeln in die oberste Ebene ist für mich jedoch nicht interessant, da dies lokales Wissen über Komponenten im gesamten System verteilen würde.

Was die Cygwin Wege: ich darauf, die Build mit relativen Pfaden arbeite. Dies löst das /cygdrive/c Problem (wie Compiler im Allgemeinen/Pfaden behandeln), ohne C: (was Abneigungen machen). Irgendwelche anderen Ideen?

+0

Beachten Sie, dass Sie '/' als Pfadtrennzeichen in Windows in der Regel gut verwenden können. Fast jede API-Funktion, die Pfade transparent verwendet, übersetzt sie trotzdem in '\'. – Joey

+0

In der Tat. Es ist jedoch der Laufwerksbuchstabe, der Probleme verursacht. Make behandelt nicht das: well (wie es ein Ziel definiert). Und das/cygdrive/c/wird von Windows-Anwendungen nicht erkannt. Wenn ich/cygdrive/c nach c:/übersetze, wird die von einem Compiler generierte Abhängigkeitsdatei vom Makefile nicht erkannt. – Adriaan

Antwort

3

CMake zusammen mit den dazugehörigen Tools CTest und CDASH scheinen Ihre Anforderungen zu beantworten. Es lohnt sich, es anzusehen.

Bill Hoffman (A Blei CMake Entwickler) bezieht sich auf die Recursive Make Considered Harmful Papier in einem post an der CMake Mailingliste:

...Da CMake die Makefiles für Sie erstellt, werden viele der Nachteile der rekursiven make vermieden, zum Beispiel sollten Sie die Makefiles debuggen oder gar darüber nachdenken, wie sie funktionieren. Es gibt andere Beispiele von Dingen in diesem Papier, das auch für Sie behebt.

Siehe auch this answer für "Rekursive Make - Freund oder Feind?" hier auf stackoverflow.

- Recursive Make - friend or foe?

+0

Danke; Ich werde dieser Kombination einen weiteren Blick geben. +1 für deine Mühe. – Adriaan

+0

Es ist nicht die Antwort, die ich gesucht habe, aber ich habe es immer noch akzeptiert, da es in der Tat besser sein könnte, das Problem zu vermeiden, als es in den make-Dateien zu lösen. – Adriaan

0

Ok hier ist, was ich tue:

Ich benutze ein Makefile an der Wurzel und Wildcards alle Dateien in einem Verzeichnis zu sammeln. Beachten Sie, dass ich annehme, dass foo/*. C zum Beispiel foo.so ausmachen wird. Dies macht die Pflege des Makefiles minimal, da nur das Hinzufügen einer Datei zum Verzeichnis automatisch zum Build hinzugefügt wird.

Da es make Sie verwenden, nehme ich an (ich mache das für meine Projekte), dass ein Compiler verwendet wird, der gcc (cc) kompatible Befehlszeilensyntax verwendet. MSC ist also nicht in Ordnung. aber nicht frustriert, ich mache die meiste meiner Entwicklung (leider) unter Windows und verwende MinGW mit MSys; klappt wunderbar. Produziert native Binärdateien, wurde jedoch mit einer Posix-konformen Build-Umgebung erstellt.

Die Abhängigkeitsprüfung erfolgt mit dem etwas standardmäßigen -MD Switch. Ich schließe dann alle * .d Dateien in das Makefile ein. Ich erstelle die Muster aus den automatisch gesammelten Quelldateien.

Abschließend werden Komponententests mit dem Ziel "Standard" check implementiert. Das Überprüfungsziel ist wie das Alles-Ziel, außer es hängt vom Komponententest ab und führt es aus, sobald alles erstellt ist. Ich mache es so, dass Sie einfach das Projekt erstellen oder die Komponententests (und den Rest des Projekts) getrennt erstellen können. Wenn ich das Projekt nicht entwickle, möchte ich es einfach bauen und damit fertig werden. Hier

ist ein Beispiel dafür, wie ich es tun: https://github.com/rioki/c9y/blob/master/Makefile Es ist auch die install, uninstall und dist Ziele hat.

Wie Sie sehen können, ist alles klar machen, keine rekursiven Aufrufe und alles ist relativ einfach. Ich habe Automake und Autoconf benutzt und ich werde das nie wieder machen; auch andere build tools kommen nicht in frage, wenn ich foojam oder barmake installieren muss, um etwas aufzubauen, ziehe ich normalerweise dieses projekt sofort ab.

Verwandte Themen