Externe Libraries in Verbindung mit Codeblocks
Auch wenn du - wahrscheinlich aus guten Gründen - anders vorgehen möchtest als hier beschrieben, empfehle ich doch, diesen Artikel zu lesen. Grund: In den Folgebeiträgen nehme ich darauf Bezug. Es geht also um das Verständnis der Folgebeiträge.
Warum Codeblocks?
Codeblocks ist eine komfortable Entwicklungsumgebung zum Erstellen von C/C++-Programmen. Sie kann nicht nur unter Windows, sondern auch unter Linux oder MacOS betrieben werden. Die IDE unterstützt verschiedene Compiler; wenn jedoch plattformübergreifend (z.B. Linux + Windows) gearbeitet wird, dürfte der GNU-Compiler GCC (über MinGW) der bevorzugte sein, weil dann auch der Code weitgehend austauschbar ist.
Codeblocks ist relativ schnell, wesentlich schneller als die monströse, schwerfällige IDE von Visual C++. Trotzdem ist Codeblocks sehr leistungsfähig und komfortabel konfigurierbar. Die Oberfläche ist trotz der vielen Optionen relativ logisch strukturiert und somit einfach zu bedienen, wiederum im Gegensatz zu den oft kryptischen Dialogen von Visual C++.
Ein Vorteil, nämlich dass sowohl unter Linux als auch unter Windows derselbe Compiler benutzt werden kann, ist gleichzeitig ein Nachteil. Da ja unter Windows die Unix-Umgebung nachgebildet wird, sind spezielle Libraries erforderlich, wenn es um Erweiterungen mit externem Code geht. Nicht alle Engines oder Libraries unterstützen dies hinreichend.
Installation externer Libraries in Codeblocks unter Windows
Das Ordnersystem
Die Installation besteht in der Regel lediglich darin, die Lib-Dateien, Header und DLLs für Codeblocks verfügbar zu machen, also Codeblocks mitzuteilen, wo sich diese Dateien befinden. Wenn man eine heruntergeladene externe Library ausgepackt hat, findet man meistens einen mehr oder weniger umfangreichen Dateibaum vor, mit diversen Unterordnern. Manchmal muss das Ganze noch kompiliert werden, manchmal ist alles gebrauchsfertig. Theoretisch könnte man diesen Dateibaum an einen günstigen Ort verschieben, um dann nur noch in Codeblocks die Pfade dorthin zu legen, aber das wird auf die Dauer ziemlich unübersichtlich. Besser ist es, die nur benötigten Dateien herauszupicken und in ein Ordnersystem rund um Codeblocks zu kopieren. Wie ein solches Ordnersystem bei mir aussieht, soll hier kurz skizziert werden. Das Ganze befindet sich auf der Datenpartition D:
D:\ Codeblocks\ projects SDL-Basisprogramm Bullet_test01 Bullet_test02 ... lib include gl SDL irrlicht bullet ... media code doc dll SDL Downloads\
Im Ordner projects befinden sich die mit Codeblocks eingerichteten Programmprojekte. Wenn man beim ersten Projekt diesen Ordner angibt, wird der auch für alle weiteren Projekte verwendet, so dass man diese alle schön beisammen hat.
Im Ordner lib befinden sich alle kompilierten Zusatzlibraries, z.B.
libSDL.dll.a
SDL_mixer.lib
...
Der Unterordner include enthält natürlich alle Header. Die Unterordner sind wichtig, da einige Pakete mit einer Vielzahl von Headern daherkommen. Die Übersicht ginge verloren, wenn man alles in einen einzigen Ordner packen würde. Im Programm werden dann diese Unterordner in der Include-Anweisung mit angegeben, da die Suchpfade in Codeblocks nicht auf jeden Unterordner eingestellt werden können, also z.B.
Die Ordner media, code und doc spielen eine untergeordnete Rolle. Hier sind Dinge untergebracht, die nur am Rande etwas mit dem Programmieren zu tun haben, z.B. allgemeine Hilfestellungen, Notizen oder grafisches Zeug zum Testen. Im Ordner code speicher ich Quelltexte von Programmen oder Programmteilen, die allgemein verwendbar sind - oder die ich einfach nur als Vorbild nehme, wenn ich etwas so ähnlich machen möchte. Es sammelt sich mit der Zeit enorm viel an.
Bleibt der Ordner dll. DLLs sind Laufzeitbibliotheken und müssen nicht vom Kompiler, sondern von Windows gefunden werden. Von daher bietet sich an, die DLLs, die Bestandteil einer externen Libraries sind, nach
C:\Windows\system32
zu kopieren. Doch davon wird allgemein - zu Recht - abgeraten, haupstsächlich deshalb, weil DLLs weiterentwickelt werden und die Versionen nicht am Dateinamen erkennbar sind. Hier sind also Konflikte möglich, die nur dann sicher vermeidbar sind, wenn man dem Program die passende DLL unmittelbar beigibt. Der Platz dafür ist der Ordner, der die EXE-Datei enthält. Da in Codeblocks meistens mehrere EXE-Dateien (= Targets) verwaltet werden (z.B. Debug und Release), kann man die DLL während der Entwicklungszeit auch im Ordner mit den Quelltexten unterbringen.
Unabhängig davon sollte man alle hinzugekommenen DLLs in dem gemeinsamen Unterordner dll speichern. Nun könnte man hingehen und in Windows (nicht Codeblocks) den Suchpfad dahin erweitern. Dann hätte man zwar die hinzugekommenen DLLs von den vielen bereits vorhandenen DLLs getrennt (immerhin ein Vorteil), aber mögliche Versionsprobleme hätte man damit noch nicht vermieden. Deshalb ist es am besten, den DLL-Ordner nur als Container zu verwenden, aus dem bei Bedarf die geeignete DLL herausgeholt geholt werden kann. Allerdings muss auch hier erkennbar sein, wozu die DLLs passen; deshalb die Unterordner.
Einstellungen der Suchpfade in Codeblocks
In Codeblocks müssen die Ordner lib und include gefunden werden, deshalb werden sie dort eingetragen. Das kann auf verschiedenen Ebenen geschehen:
- Allgemein. In diesem Fall stehen die Einstellungen ohne weitere Maßnahmen für alle Projekte zur Verfügung. Die Einstellungen erfolgen im Menü <Settings>, dann <Compiler and debugger/Search directories>. Unter <Compiler> wird der Pfad zum Include-Ordner, unter <Linker> der Pfad zum Lib-Ordner eingestellt.
- Auf einzelne Targets bezogen. Diese Einstellung gilt nur für das gerade aktivierte Target (z.B. Debug oder Release oder ...). Der Dialog ähnelt dem oben beschriebenen, nur wird er über Rechtsklick auf den Projektknoten, dann <Build options> erreicht. (Oder Projekt-Menü)
- Meistens wird man, was die Pfade betrifft, keinen Unterschied zwischen den Targets machen. Dann ist es einfacher, die Einstellung für alle Targets, also das gesamte Projekt, vorzunehmen. Das geschieht ebenfalls über <Build options>, allerdings wird im linken Fenster ganz oben das Projekt anstatt eines ausgewählten Targets aktiviert.
Wenn man, wie oben beschrieben, ein dauerhaftes Ordnersystem aufgebaut und gepflegt hat, spricht nichts dagegen, die Einstellungen einmalig und allgemein vorzunehmen.
Registrierung der Libraries in Codeblocks
Neben den Pfaden muss Codeblocks darüber informiert werden, welche Libraries gelinkt werden sollen. Man kennt diese Auflistung, wenn man den Compiler auf der Kommandozeile aufruft. Ähnlich sieht es im Makefile aus, dort werden die Libraries meistens in der Variablen LDFLAGS zusammengefasst. Beispiel:
Ähnlich geht es in Codeblocks, wo die Libraries registriert werden müssen. Dazu geht man in <Build options> auf die Seite <Linker settings>. Nun hat man zwei Möglichkeiten. Entweder trägt man eine Zeile in das rechte Feld (<Other link options>) ein, und zwar in der Form wie oben gezeigt, mit -l und angehängtem Namen. Oder man listet im linken Feld die Libraries untereinander auf, z.B.
OpenGL32
GLU32
SDLmain
SDL
SDL_image
Wichtig: Die Reihenfolge ist nicht immer beliebig, weil manche Libraries von anderen abhängen können.
Am besten stellt man links oben das gesamte Projekt ein, damit die Einstellungen für alle Targets gelten
Installation externer Libraries in Codeblocks unter Linux
Die Linux-Version von Codeblocks ist praktisch identisch mit der Windows-Version; insofern gilt das Gesagte ebenso für Linux, das meiste jedenfalls. Unterschiede gibt's bei den Libraries. Diese werden oft - wenn nicht sogar meistens - direkt im System installiert, also an einem der Orte
/usr/local/lib
Dort werden sie automatisch gefunden, so dass der Pfad nicht in Codeblocks eingetragen werden muss. Ähnliches gilt für die Header, die an einem der Orte
/usr/local/include
zu finden sind. Wenn man eine externe Library aus den Sourcen kompiliert, hat man natürlich die Wahl, wo man die Dateien unterbringt. Man kann sie in die genannten Ordner kopieren, man kann sie aber auch, wie oben beschrieben, in einem eigenen Ordnersystem sammeln. Ein weiterer Unterschied besteht darin, dass die Laufzeitbibliotheken unter Linux anders sind. Das Pendant zu den DLLs sind Lib-Dateien mit der Endung .so. Diese müssen - ebenso wie die DLLs - immer vorhanden sein, nicht nur während der Entwicklungszeit. Somit spricht vieles dafür, die Libraries in den dafür vorgesehenen Orten zu installieren. Der spätere Benutzer kommt ohnehin nicht drumherum, das eine oder ander ordnungsgemäß mitzuinstallieren. Das ist halt Unix-gemäß.