Kompilieren und make - einige Fragen

  • Kompilieren und make - einige Fragen

    hallo zusammen,

    ich habe heute begonenn mich mit dem Thema "make" auseinanderzusetzen.
    Scheint ja ne Prima Sache zu sein, wirft allerding für mich erstmal einigen Fragen auf (auch zum Vorgang des Kompilierens an sich).

    1. Ich habe gelesen, das man unter Windows mit dem Borlandcompiler beim Aufruf auf der Kommandzeile den Pfad zu den Bibliotheken und include Dateien explizit angeben muss*äächz*.
    Woher weiss z. B gcc oder g++ oder XCode den Pfad zu diesen Verzeichnissen.
    Denn da muss ich den Pfad ja nie angeben.

    2. Beim Aufruf von gcc etc. werden doch sicher auch Objektdateien und sowas angelegt.
    Werden diese Dateien automatische wieder gelöcht, oder bleiben die auf der Platte liegen ?
    Wo werden diese Dateien angelegt ?

    3. Wenn ich es richtig verstanden habe, kann man make auch zu allerlei anderer nützlicher Aufgaben "miss"brauchen.
    Spontan ist mir eingefallen, ein kleines backup Skript in ein Makefile zu schreiben.
    Das Makefie könnte man in diversen Verzeichnissen ablegen um dann durch einen Aufruf von "make backup" (evtl per Cronjob) ein backup sämtlicher Dateien und Unterverzeichnisse zu machen.

    Ob das nun optimal ist sei einmal dahingestellt - soll ja uch nur ein Beispiel sein, aber:
    Würde das klappen ?
    Habe Mut, Dich Deines eigenen Verstandes zu bedienen.
    (Immanuel Kant)
  • 1. [...] Denn da muss ich den Pfad ja nie angeben.

    Das kommt ja ganz darauf an, was Du machst. Aber unter Unix gibt es ein paar standard Verzeichnisse, z.B. /usr/include/ und /usr/lib/, die kennt der Compiler schon.

    2. Beim Aufruf von gcc etc. werden doch sicher auch Objektdateien und sowas angelegt.

    Wenn keine Datei mit -o angegeben wurde, wird der Objektcode in die Datei a.out geschrieben

    3. Wenn ich es richtig verstanden habe, kann man make auch zu allerlei anderer nützlicher Aufgaben "miss"brauchen.

    Ja ;)

    Gruss, Alex
    The only thing that really worried me was the ether.
  • RE: Kompilieren und make - einige Fragen

    Original von D.Mon(SNIPPED)
    1. Ich habe gelesen, das man unter Windows mit dem Borlandcompiler beim Aufruf auf der Kommandzeile den Pfad zu den Bibliotheken und include Dateien explizit angeben muss*äächz*.
    2. Beim Aufruf von gcc etc. werden doch sicher auch Objektdateien und sowas angelegt. Wo werden diese Dateien angelegt ?
    3. Wenn ich es richtig verstanden habe, kann man make auch zu allerlei anderer nützlicher Aufgaben "miss"brauchen. Spontan ist mir eingefallen, ein kleines backup Skript in ein Makefile zu schreiben.

    zu 1. die meisten Pfade sind im XCode-Projekt angelegt und werden beim Aufruf an gcc übergeben. Wenn Du Dir mal die detailierte Übersicht beim Build ansiehst, dann wirst Du sehen wieviele Parameter da übergeben werden. Am besten ist, Du erzeugst im Makefile eine Variable, die alle wichtigen Optionen enthält. Diese können auch in externen Dateien liegen, die vom aktuellen Makefile importiert werden.

    zu 2. die Objekt Dateien bleiben eigentlich immer liegen. Du gibst gcc aber immer an wohin das Objekt-File geschrieben werden soll (Dateiname genauso wie Pfad). Du kannst Dir die Object-Dateien auch in ein Unterverzeichnis anlegen lassen, dass Du nach dem make wieder aufräumst. Allerdings ist das Object-File das Ergebnis des kompilierens. Wenn Du die Object-Files gleich löscht, dann muss jedesmal alles neu kompiliert werden, da sonst zum einen die Dependancies nicht erfüllt sind und zum anderen die Object-Files der Input für den Linker sind. Am besten wirfst Du mal einen Blick in die Man-Pages vom gcc - aber die sind sehr umfangreich. Wir haben dazu ein "Tidy" target in jedem Makefile, dass alle Objekt-Dateien entfernt - haptsächlich um beim Archivieren Platz zu sparen, da wir unsere Programme mit verschiedenen Kompilern für verschiedene Betriebssysteme kompilieren.

    zu 3. du kannst damit alles erledigen, was mit Abhängigkeiten von Dateien darstellbar ist. So ein Backup würde auf jeden Fall gehen, aber das ist nicht so einfach - ich habe sowas ähnliches schon gemacht. Wir hatten mal ein Netzwerk mit seinen Abhängigkeiten zwischen den Servern in Makefiles abgebildet. Wenn ein Rechner zu Wartungszwecken vom Netz genommen werden musste, dann wurde dessen "Datei" geändert. Ein Aufruf von make hatte dann alle Server und Dienste aufgelistet, die dadurch beeinträchtigt wurden. Mit make kann man die irrsten Sachen anstellen. Diese Backup-Sache klappt ganz sicher auch damit, es ist aber nicht ganz so einfach, wie es aussieht.
  • hallo zusammen,

    Danke für Eure Hilfe.

    Ich glaube ich habe mich falsch ausgedrückt:
    mit -o wird doch der Name der ausführbaren Datei angegeben (ohne Angabe a.out)

    Mit Objektdatei meinte ich aber die Zwischendatei, die wohl die Endung *.obj trägt und dann gar nicht mehr gebraucht wird.
    Wie die richtig heisst, weiss ich gar nicht

    @ ssb
    Du gibst gcc aber immer an wohin das Objekt-File geschrieben werden soll (Dateiname genauso wie Pfad)

    also ich mach das immer so:

    gcc -o programm programm.c

    der Quelltext steht in "programm.c"; das fertige Programm heisst dann "programm".
    Objectfiles hab ich da noch nie zu Gesicht bekommen
    Habe Mut, Dich Deines eigenen Verstandes zu bedienen.
    (Immanuel Kant)
  • When you invoke GCC, it normally does preprocessing, compilation, assembly and linking.
    man gcc

    In einerem größeren Projekt werden erst Objektfiles erzeugt, und dann später gelinkt.
    Bei gcc -o myprog proc.c wird direkt alles gemacht.

    Gruss, Alex
    The only thing that really worried me was the ether.
  • RE: Kompilieren und make - einige Fragen

    Original von D.Mon
    2. Beim Aufruf von gcc etc. werden doch sicher auch Objektdateien und sowas angelegt.
    Werden diese Dateien automatische wieder gelöcht, oder bleiben die auf der Platte liegen ?
    Wo werden diese Dateien angelegt ?

    Beim Compilieren per Xcode zum Beispiel, werden die Objektdateien und auch noch Anderes in einen extra Ordner innerhalb des Projektordners abgelegt. Der Ordner heißt <Projektname>.build.

    Michael
  • Ich muss den letzen Posts zustimmen. Wenn man ein Projekt mit nur einem Quelltext hat, dann kann man alles auf einen Rutsch erledigen. Genau genommen in drei Teilschritten:
    c/cpp/m -> s (Assembler)
    s -> o (Object)
    o + libs -> fertiges Programm
    Die Zwischenergebnisse werden vom gcc immer in /tmp gelegt und nach Gebrauch gelöscht. Man kann gcc aber auch per Option anweisen, die Temp-Files nicht zu löschen.

    Zudem - wenn ich gcc sage -o myfile.s, dann macht er ein Assembler-File, mit -o myfile.o, dann ein Object-File.

    Natürlich brauchst Du die Object-Files nicht, wenn Dein Projekt in ein Source-File passt, aber dann brauchst Du auch kein make. Besteht ein Projekt (wie allgemein üblich) aus mehreren Sourcen, dann musst Du beim Kompilieren Objekt-Files erzeugen, die am Schluß gelinkt werden. Die Objekt-Files können aber auch (wie bei XCode) in einem Unterverzeichnis liegen. Auf diese Weise werden mit make nur geänderte Sourcen kompiliert und falls Du die Abhängigkeiten richtig angibst, die Sourcen die von geänderten Header-Files abhängen. XCode hat dazu einen zusätzlichen C-Parser, der aus dem Quelltext die Abhängigkeiten von Sourcen und Headerfiles selbstständig aufbaut und überprüft.
  • hallo below,

    vielen Dank für Deinen Hinweis.

    Irgendwie habe ich heute wohl Probleme mich klar auszudrücken.
    Es war mir bekannt, dass diese Schritte durchgeführt werden. Darum schrieb ich ja auch "2. Beim Aufruf von gcc etc. werden doch sicher auch Objektdateien und sowas angelegt. Wo werden diese Dateien angelegt ?"

    Wenn ich die folgenden Beiträge richtig verstehe, dann wird also ein .obj nur angelegt, wenn man mehrer Sourcefiles verwendet.
    Wie sieht das aus, wenn man zB "#include<irgendwas>" verwendet ?

    Entschuldigt, wenn ich etwas schwer von Begriff bin, ich bin ein ziemlicher Anfänger.
    "make" habe ich bisher gar nicht verwendet, wollte aber jetzt mal damit anfangen.
    Um das gleich etwas strukturiert anzugehen, hilft es mir, wenn ich wenigstens ungefähr verstehe, wie das abläuft und nicht einfach nur eine Anleitung befolge.

    Beim Compilieren per Xcode zum Beispiel, werden die Objektdateien und auch noch Anderes in einen extra Ordner innerhalb des Projektordners abgelegt. Der Ordner heißt <Projektname>.build.

    So schön das ist, wenn alles automatisch geht, dem Verständnis der zugrundeliegenden Vorgänge hilft das aber erstmal nicht.
    Darum schreibe ich auch neben der Verwendung von XCode kleine Code-Beispiele mit dem vi und kompiliere "von Hand".
    Habe Mut, Dich Deines eigenen Verstandes zu bedienen.
    (Immanuel Kant)
  • Original von D.Mon
    Wenn ich die folgenden Beiträge richtig verstehe, dann wird also ein .obj nur angelegt, wenn man mehrer Sourcefiles verwendet.

    Nein. Objekt-Dateien werden dann angelegt, wenn man es dem Compiler sagt. So ergibt zum Beispiel

    Quellcode

    1. gcc -c main.c -o main.o
    die Objekt-Datei main.o. Man kann auch hinter -o einen Pfad mit angeben. Objekt-Dateien erstellt man, damit man bei Änderungen an einigen Stellen nicht alles immer wieder komplett compilieren muss, sondern nur die geänderten Dateien und die von den geänderten Dateien abhängenden Dateien. make hilft dabei die Abhängigkeiten im Griff zu behalten.

    Original von D.Mon
    Wie sieht das aus, wenn man zB "#include<irgendwas>" verwendet ?

    Das ist wieder eine andere Geschichte. Was mit "#include" geschieht, kannst Du Dir angucken, wenn du folgendes eingibst (die Ausgabe kommt direkt auf dem Terminal raus):

    Quellcode

    1. gcc -E main.c
    Michael
  • hallo nochmal,

    Danke schön für Eure Mühe und Eure Tips.

    Also die ersten Schritte mit make (bei meinen Miniprogrammen) stell ich mir so vor, dass ich nicht immer mit -o den Programmnamen angeben muss und dass ich eine install Anweisung einbaue, die mir die fertige Datei dann in ein bestimmtest Verzeichnis kopiert, das in meinem Suchpfad liegt.

    Damit würde ich mir das ./ vor dem Programmaufruf sparen.

    Außerdem dachte ich mir, müsste doch auch so eine Art Rotationsmechanismus möglich sein, der mir z. B die letzten 5 Versionen des Quellcodes wegsichert, dann könnte ich etwas unbeschwerter rumprobieren und käme leicht wieder zu meinen letzten Ständen zurück.

    Das schaffe ich aber glaube ich (bzw. hoffe ich) alleine.
    Mir gehts ja jetzt auch primär darum mich mit dem Konzept an sich auseinander zu setzen und den Einstieg zu schaffen.
    Habe Mut, Dich Deines eigenen Verstandes zu bedienen.
    (Immanuel Kant)
  • Außerdem dachte ich mir, müsste doch auch so eine Art Rotationsmechanismus möglich sein, der mir z. B die letzten 5 Versionen des Quellcodes wegsichert, dann könnte ich etwas unbeschwerter rumprobieren und käme leicht wieder zu meinen letzten Ständen zurück.

    Ein Wort: Versionskontrolle. Aber das Thema hatten wir ja schon durch ;)

    Viel Spass noch beim Lernen. Das hört übrigens nie auf, jedenfalls hoffentlich nicht.

    Gruss, Alex
    The only thing that really worried me was the ether.
  • Original von below
    Außerdem dachte ich mir, müsste doch auch so eine Art Rotationsmechanismus möglich sein, der mir z. B die letzten 5 Versionen des Quellcodes wegsichert, dann könnte ich etwas unbeschwerter rumprobieren und käme leicht wieder zu meinen letzten Ständen zurück.
    <br>
    Ein Wort: Versionskontrolle. Aber das Thema hatten wir ja schon durch ;)<br>
    ....

    Genau, aber wie Du siehst, habe ich genug zu lernen; CVS heb ich mir nochmal auf.
    Gibts übrigens im FreeBSD Handbuch auch einige Info dazu (falls das jemand interessiert)
    Viel Spass noch beim Lernen. Das hört übrigens nie auf, jedenfalls hoffentlich nicht.

    :D ja, aber wie mir scheint, werden die Nächte auch immer kürzer und die Kinder stehen plötzlich mit der Schultüte da und man fragt sich wie alt die wohl schon sind :D
    ne Quatsch; die Kinder stehen bei mir an erster Stelle, darum dauerts auch manchmal ein bischen länger bis ich was durch habe.
    Habe Mut, Dich Deines eigenen Verstandes zu bedienen.
    (Immanuel Kant)
  • mit -I gibst du den Pfad zu den optionalen includes an.
    Statische Libraries (.a) werden so mit gegeben.

    und was soll daran *ächz* sein die Pfade mitzugeben. Mit ein wenig Ordnung, ist das höchstens ein ../../include/

    Sven - Ordnung ist das halbe Leben ;)
    :wq! /dev/null
  • Original von Stalkingwolf
    ....
    und was soll daran *ächz* sein die Pfade mitzugeben. Mit ein wenig Ordnung, ist das höchstens ein ../../include/

    Sven - Ordnung ist das halbe Leben ;)

    Das sagte meine gute Großmutter auch immer :D
    Außerdem hast du das -o Programmname vergessen.

    Ne Quatsch, du hast ja Recht (Dabei dachte ich immer Programmierer sind faul).

    Aber wie ich schon sagte: Mir gehts im Wesentlichen um den Lerneffekt.
    Habe Mut, Dich Deines eigenen Verstandes zu bedienen.
    (Immanuel Kant)