Frage zu makefiles



  • hustbaer schrieb:

    Shade Of Mine schrieb:

    Wann muessen die Dependencies neu generiert werden?

    Explizit nie.

    So funktioniert das aber einfach nicht.
    Aber gut, du hast ja gesagt dass du von Buildsystemen keine Ahnung hast.

    Shade Of Mine schrieb:

    Vielleicht hat es einen Grund das kein einziger Compiler dieses Verhalten dass du dir wuenscht implementiert 😉

    **Hallo?? MSVC????
    **Hab ich nur schon 3x oder so geschrieben.
    *kopf -> wand*

    MSVC ist eine IDE und kein Compiler.
    Eine IDE mit Buildsystem.

    Bezeichnend wie du so schnell Beleidigend wirst...



  • Shade Of Mine schrieb:

    So funktioniert das aber einfach nicht.
    Aber gut, du hast ja gesagt dass du von Buildsystemen keine Ahnung hast.

    Naja, so explizit habe ich das glaube ich nicht gesagt. Bin aber sicher nicht der Experte, das stimmt schon. Andrerseits ist die Sache ausreichend einfach so dass man wohl kein Experte sein muss um sich überlegen zu können was möglich wäre.

    Was das "so funktioniert das aber einfach nicht" angeht...
    Ich glaube dir schon dass es aktuell so nicht funktioniert. Weil die .d Files eben keine Informationen über Switches etc. beinhalten. In meinem Beispiel würden sie das aber, bzw. würden die nötigen Informationen in den .o Files stehen. Und dann sehe ich keine Notwendigkeit die Dependencies überhaupt irgendwann neu zu generieren.

    MSVC ist eine IDE und kein Compiler.
    Eine IDE mit Buildsystem.

    Ich meinte mit MSVC ja auch nur den Compiler.
    Sorry, es war für mich nicht klar dass du davon ich würde die ganze IDE meinen, wenn ich doch mehrfach schreibe dass ich nur den Compiler meine. BTW: Wenn "MSVC" für dich die IDE mit einschliesst, was schreibst du dann wenn du nur den Compiler meinst?

    Davon abgesehen hab ich diesen Punkt aber nochmal etwas nachrecherchiert, und ... naja, da hatte ich wohl ebenso falsche Informationen. Soll heissen: ich war der ehrlichen Meinung dass der Visual C++ Compiler (ohne IDE!) selbst entscheidet was neu gebaut werden muss und was nicht. Hab das in einigen Beiträgen (Stackoverflow, ...) so gelesen und einfach mal geglaubt. Ich hab' jetzt allerdings andere Beiträge gefunden die darauf hindeuten dass doch MSBuild sich darum kümmert. (Ich habe auch versucht eine "offizielle" Beschreibung zu finden wie C++ Builds mit MSBuild funktionieren, inklusive Beschreibung wie die Sache mit den include-Dependencies gelöst wird. Konnte aber nix finden.)



  • hustbaer schrieb:

    In meinem Beispiel würden sie das aber, bzw. würden die nötigen Informationen in den .o Files stehen. Und dann sehe ich keine Notwendigkeit die Dependencies überhaupt irgendwann neu zu generieren.

    Machen wir doch mal ein kleines Beispiel:

    a.c:

    #include "b.h"
    

    b.h:

    #include "c.h"
    

    Welche Information würdest Du in der a.o hinterlegen? Was passiert, wenn die b.h geändert wird zu

    #include "d.h"
    

    ?



  • Welche Information würdest Du in der a.o hinterlegen?

    `

    built with path/to/a.c {datum}

    built with path/to/b.h {datum}

    built with other_path/c.h {datum}

    built with switches {XYZ}

    built with compiler version {XYZ}

    ...

    `

    Was passiert, wenn die b.h geändert wird zu

    Das changed-date von b.h ändert sich, und der Test gegen
    built with path/to/b.h {datum}
    ergibt dass neu gebaut werden muss?

    Das Beispiel funktioniert aber auch noch wunderschön mit klassischen, externen .d Files 😉



  • hustbaer schrieb:

    Und dann sehe ich keine Notwendigkeit die Dependencies überhaupt irgendwann neu zu generieren.

    Du brauchst immer ein Clean. Immer. Egal was.
    Und da wird es doof wenn der Compiler dein Make-Clone ist. Denn du brauchst ein make clean, ein make all, ein make target, etc.

    Sobald du Metainformationen generierst, musst du diese auch handeln.

    Wenn wir jetzt davon ausgehen dass wir nie auf diese Metadaten zugreifen muessen und das System mit den Compilern perfekt funktioniert: welchen Vorteil haettest du?

    Du brauchst immer noch ein Buildsystem. Abhaengigkeiten gibt es viel mehr als nur die Includes. Mehrere Buildschritte, unterschiedliche Targets, etc. Du wuerdest dir hier deutlich mehr Komplexitaet einkaufen, weil Compiler ploetzlich "mitdenken" und das beachtet werden muss.

    Das tolle an dem Unix-Ansatz ist ja, dass jede Anwendung nur fuer einen kleinen Teil zustaendig ist und das man sich komplexe Loesungen baut indem man viele kleine Anwendungen aneinander stoppelt.

    Also ja, wenn du unbedingt willst dass der Compiler die Dependencies aufloesen soll, dann soll er das machen. Aber er soll bloss nicht versuchen ein mini-make zu sein.



  • Shade Of Mine schrieb:

    hustbaer schrieb:

    Und dann sehe ich keine Notwendigkeit die Dependencies überhaupt irgendwann neu zu generieren.

    Du brauchst immer ein Clean. Immer. Egal was.
    Und da wird es doof wenn der Compiler dein Make-Clone ist. Denn du brauchst ein make clean, ein make all, ein make target, etc.

    OK, so meinst du das. Ja, geht ja alles. Make clean = alle Intermediate-Files löschen. So lange man die Metadaten (d.h. Dependencies oder was sonst noch anfällt) in Files speichert geht das ja. Und wenn man die Intermediate-Files in einem eigenen Verzeichnis sammelt, ist das hübsch einfach und unabhängig davon welche Filenamen/Extensions irgendwelche Tools produzieren/verwenden. Einfach das ganze Verzeichnis löschen und gut.

    Shade Of Mine schrieb:

    Wenn wir jetzt davon ausgehen dass wir nie auf diese Metadaten zugreifen muessen und das System mit den Compilern perfekt funktioniert: welchen Vorteil haettest du?

    Du brauchst immer noch ein Buildsystem. Abhaengigkeiten gibt es viel mehr als nur die Includes. Mehrere Buildschritte, unterschiedliche Targets, etc. Du wuerdest dir hier deutlich mehr Komplexitaet einkaufen, weil Compiler ploetzlich "mitdenken" und das beachtet werden muss.

    Mir geht es dabei darum dass ein generisches Tool wie make (bzw. ein anderes Build-System) nichts über die Eigenheiten der Sprache wissen sollte.
    Beim Programmieren irgendwelcher Anwendungen würde man das ja auch nicht so machen. Also zwei strikt getrennte Module zu machen (unterschiedliche Hersteller, getrennt versioniert etc.), von denen eines über die "Innereien" des anderen Bescheid wissen muss, damit es "voraussagen" kann was das andere Modul brauchen wird um irgend eine Aufgabe zu erledigen.

    Damit dass man den Compiler verwendet um die Liste der Dependencies zu erzeugen vermeidet man natürlich einen Teil der Probleme. Allerdings hat man dann immer noch eine Schnittstelle zwischen den beiden Tools die eigentlich unnötig ist. Und Probleme verursachen kann, z.B. dadurch dass sie bestimmte Dinge nicht kann/versteht. z.B. ist die Schnittstelle wie sie momentan verwendet wird - wenn ich es richtig verstanden habe - dahingehend limitiert, dass make nicht feststellen kann wenn sich include-Verzeichnisse geändert haben. Das muss der User dann wissen und manuell clean aufrufen.
    Und das könnte man mMn. eben vermeiden.

    Andere Frage dazu: Kann make korrekt mit gleichnamigen .c und .h Files in verschiedenen Verzeichnissen umgehen?

    Shade Of Mine schrieb:

    Das tolle an dem Unix-Ansatz ist ja, dass jede Anwendung nur fuer einen kleinen Teil zustaendig ist und das man sich komplexe Loesungen baut indem man viele kleine Anwendungen aneinander stoppelt.

    Mir der "Unix-Ansatz" schon klar. Mir ist aber auch klar zu welchen Problemen er führt wenn man versucht überall damit zu arbeiten. Und speziell wenn man es macht ohne zu berücksichtigen was es für Folgen hat. Dabei fällt mir z.B. die tolle Idee ein den Output von tar direkt nach gzip rein-zu-pipen. Was dann dazu führt dass Fehler die tar meldet einfach gefressen werden. (Oder gibt es auch dazu eine Lösung die ich bloss nicht kenne?)

    Aber zurück zu Build-Systemen. Sagen wir ich schreibe einen C# Compiler. Oder auch einen Compiler für eine ganz neue Sprache X. Und sagen wir dieser C# bzw. X Compiler braucht zwei Durchgänge die man getrennt aufrufen muss. Einen um die Metadaten der in den Source-Files definierten Klassen zu extrahieren, und einen zweiten der diese Metadaten dann verwendet (damit er weiss was für andere Klassen existieren und wie diese aussehen) um das eigentliche Kompilat zu erstellen.
    Würdest du dafür dann das Build-System erweitern wollen, damit man diesen C# bzw. X Compiler verwenden kann? Was wenn Version 2 dieses Compilers beschliesst statt einem Metadaten-File pro Source-File nur ein einziges Metadaten-File zu verwenden in dem er alle Metadaten sammelt? Müssen wir dann alle Build-Tools anpassen?

    Ich würde es nicht wollen. Ich würde sagen: Was der komische X Compiler da mit den zwei Durchgängen macht, das soll er gefälligst so machen dass das Build-System davon nichts wissen muss. D.h. der X Compiler soll ein Frontend bereitstellen das man mit allen Source Files auf einmal aufrufen kann, und sich um seine Durchgänge, Intermediate-Files und interne Abhängigkeiten selbst kümmern.

    Und das selbe würde ich eben auch für C oder C++ Compiler sagen.


Anmelden zum Antworten