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.
-
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 auchint foo() {return 1;}
-
hustbaer schrieb:
immer diese pseudo-minimalisten.
es reicht auchint 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?
-
Du vergleichst da Äpfel mit
BirnenApfelbä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.