Builtsysteme verstehen



  • Hallo Forenmitglieder.

    Bereits seit einiger Zeit versuche ich nun mir das Programmieren
    beizubringen, bisher leider mit eher mäßigem Erfolg. Dies liegt
    zum Großteil daran, dass ich bereits bei der Einbindung von weiteren
    Bibliotheken scheitere. Ich verstehe einfach den Aufbau komplexerer
    Makefiles nicht bzw. komplexerer Builtsysteme.
    Das fängt dabei an, dass mir bereits der Begriff der Library
    als etwas schwammig erscheint. Handelt es sich dabei um eigene
    Sourcecodes oder um binaries?
    An welcher Stelle wird die Library in mein Projekt eingebunden?
    Sagen wir, wir haben eine libraryX mit der Funktion fooX()und linken
    diese zu unserem Projekt. Kann man dann fooX() einfach aufrufen, nachdem
    man sie bekannt gemacht hat (z.B. mit #include "libraryX.h")?
    Woher weiß mein Sourcefile dann, wo die libraryX.h liegt und
    welchen Zusammenhang gibt es überhaupt zwischen header files und
    object files?
    Und muss man die Bibliotheken vorher erst selbst kompilieren, mit
    allen internen Abhängigkeiten?

    Hoffentlich habe ich mein Problem mit den Builtsystemen nicht zu
    schwammig formuliert. Ich kann es leider nicht weiter präzisieren,
    da es eher ein allgemeines Problem ist. Ein Link zu einer Seite
    über den allgemeinen Aufbau eines Makefiles würde mir aber eher
    weniger helfen. Es geht mir eher um das Verständnis darum, wie ein
    Projekt allgemein intern zusammengehalten wird.

    Entschuldigt den langen Text, aber ich wüsste nicht wie
    ich es kürzer hätte fassen sollen.

    Danke für das lesen meines Beitrages.
    Hoffe ihr könnt mir helfen.


  • Mod

    Samuel25 schrieb:

    Entschuldigt den langen Text, aber ich wüsste nicht wie
    ich es kürzer hätte fassen sollen.

    Ein
    erster
    Schritt
    wären
    weniger
    Z
    e
    i
    l
    e
    n
    u
    m
    b
    r
    ü
    c
    h
    e
    .



  • - Eine Library kann kompiliert sein. Muss aber nicht.

    An welcher Stelle wird die Library in mein Projekt eingebunden?

    Du includierst erst mal nur den Header. Der Compiler muss wissen, wo die Library liegt.

    An welcher Stelle wird die Library in mein Projekt eingebunden?
    Sagen wir, wir haben eine libraryX mit der Funktion fooX()und linken
    diese zu unserem Projekt. Kann man dann fooX() einfach aufrufen, nachdem
    man sie bekannt gemacht hat (z.B. mit #include "libraryX.h")?

    Ja.

    Woher weiß mein Sourcefile dann, wo die libraryX.h liegt und
    welchen Zusammenhang gibt es überhaupt zwischen header files und
    object files?

    Das musst du dem Compiler mitteilen. Siehe -L und -I Option im gcc.
    Zwischen Header- oder Object-Files gibt es keinen direkten Zusamenhang. Object Files wurden in Maschinencode kompiliert und man kann einzelne Object-Files zu einer größere ausführbaren Datei "zusammenschmelzen" lassen. Das geht auch wieder über den Compiler.

    Ein Link zu einer Seite über den allgemeinen Aufbau eines Makefiles würde mir aber eher weniger helfen.

    Doch, das würde dir ungemein helfen!

    L. G.
    Steffo



  • Am meisten würde dem TS helfen, wenn er mal seine eigene kleine Bibliothek erstellt und compiliert.

    Die muss auch nicht viel können.
    pow(x,y);
    add(x,y);
    sub(x,y);
    div(x,y);

    reicht eigentlich schon und diese lib sollte er dann mal von einem Testprogramm aus nutzen.



  • Hallo nochmal, und Danke für die bisherigen Antworten.

    Ich habe mir den Hinweis zu Herzen genommen und ersteinmal eine eigene kleine Library geschrieben. Dazu habe ich die Library mit "g++ -c myLib.cpp -o myLib.o" kompiliert und anschließend mit "ld -shared myLib.o -o libmyLib.so" gelinkt (ich habe mich für eine shared library entschieden, da der Kompiler sonst einfach nur die object-Datei wie jedes andere Objekt meines projektes einfach integriert hätte). Danach habe ich folgendes Makefile geschrieben:

    CC = /usr/bin/g++
    CFLAGS = -Wall
    CLIBS = -LmyLib -lmyLib
    
    OBJ = main.o
    
    all: $(OBJ)
    	$(CC) $(CFLAGS) -o myLibProg $(OBJ) $(CLIBS)
    
    %.o: %.c
    	$(CC) $(CFLAGS) -c $<
    

    Folgend habe ich mein Projekt mit make kompiliert und noch die libmyLib.so nach /usr/lib kopiert, damit mein Programm sie finden kann. Eigentlich funktioniert es so auch, nur dass ich in meinem Projekt den header über '#include "myLib/myLib.h"' inkludieren musste, damit er gefunden wird. Ist es also notwendig immer den ganzen Pfad zum Header anzugeben?

    Und habe ich das richtig verstanden, dass wenn man dem Compiler die Library und dem Sourcefile den Standort der Library-Header mitgeteilt hat einfach die Funktionen der Bibliothek verwenden kann, ohne weitere Schritte?



  • immer diese pseudo-minimalisten.
    es reicht auch int foo() {return 1;}



  • hustbaer schrieb:

    immer diese pseudo-minimalisten.
    es reicht auch int foo() {return 1;}

    Warum nicht gleich void f() {} ?



  • Samuel25 schrieb:

    Eigentlich funktioniert es so auch, nur dass ich in meinem Projekt den header über '#include "myLib/myLib.h"' inkludieren musste, damit er gefunden wird. Ist es also notwendig immer den ganzen Pfad zum Header anzugeben?

    Und habe ich das richtig verstanden, dass wenn man dem Compiler die Library und dem Sourcefile den Standort der Library-Header mitgeteilt hat einfach die Funktionen der Bibliothek verwenden kann, ohne weitere Schritte?

    1. Du musst immer einen include machen, wenn du eine lib benutzt!
    2. Solltest du auf keinen Fall irgendwelche Pfade im Header angeben, weil das auf unterschiedlichen Rechnern zu Problemen führen kann! Mache das stattdessen über den Linker, in dem zu ihm mitteilst, wo er suchen muss. Das kannst du übrigens auch wunderbar über gcc machen, der dann den Linker für dich aufruft. Mit -L gibst du den Ordner an, wo der Linker nach einer lib suchen soll. Mit -ldeinLibName, gibst du den Libnamen an, wobei erwartet wird, dass deine lib mit "lib" anfängt und in deinem Fall mit ".so" endet. WICHTIG: Bei der Option -ldeinLibName lässt du das "lib" vorne und das ".so" hinten weg!

    L. G.
    Steffo



  • Für die meisten Compiler gibt es komfortable Entwicklungsumgebungen (IDE). Diese nehmen dem Programmentwickler das Erstellen von Makefiles ab. Wenn du die Makefiles verstehen willst, musst du zunächst einen Überblick haben, was ein Compiler und was ein Linker macht. Compiler: Sourcecode (C/C++) --> Binärobjekte (obj). Linker: Binärobjekte --> Programm (exe).
    Die Standardbibliotheken werden über Headerfiles mit #include dem Compiler mitgeteilt und vom Linker gebrauchsfertig eingebunden. Eigene unabhängig erstellte Bibliotheken (lib) brauchen etwas mehr: die Funktionsprototypen für den Compiler und die Benennung der LIB-Files für den Linker.

    Verstehe erst einmal dies!



  • Zum weiteren Verständnis habe ich mein Makefile mal auf
    eine richtige Bibliothek hin angepasst um zu sehen ob es funktioniert.

    CC = c:/MinGW/bin/g++.exe
    CFLAGS = -Wall
    CLIBS = -LC:/irrlicht-1.7.2/lib/Win32-gcc -lIrrlicht
    
    OBJ = main.o
    
    all: $(OBJ)
    	$(CC) $(CFLAGS) -o myLibProg $(OBJ) $(CLIBS)
    
    %.o: %.c
    	$(CC) $(CFLAGS) -c $<
    

    Da dies auch wunderbar funktionierte, habe ich mich mal noch ein Stück weiter vorgewagt, und versucht es auf CMake zu portieren. Und da bin ich wieder beim ursprünglichen Problem: CMake (und die autotools auch, nur dass die NOCH schwerer zu verstehen sind) scheint nur Libraries zu kennen, die direkt aus dem Sourcecode kompiliert werden. Ein Beispiel für einfaches Linken zu einer shared library wie es das Makefile oben macht hat mir Google nicht geliefert.
    Kann mir jemand schreiben, wie obiges Makefile mit CMake aussehen würde?


  • Mod

    Du vergleichst da Äpfel mit Birnen Apfelbäumen. cmake ist kein direkter Ersatz für make. cmake steht eher in Konkurrenz mit den autotools (also der Kombination von autoconf, automake & Co) und anderen Buildsystemen wie z.B. Scons. Also eine Ebene höher als das typische Makefile.


Anmelden zum Antworten