Visual Studio EXE in LIB Projekt ändern
In diesem Tutorial zeige ich wie man unter Visual Studio eine Anwendung (EXE) in eine LIB Projekt ändert. Damit ist die Codebasis in anderen Projekten verfügbar.
Visual Studio EXE in LIB Projekt ändern
Ich arbeite aktuell in einer Visual Studio Projektmappe in der sich 3 Projekte befinden. Alle 3 bauen eine ausführbare *.exe Datei und haben folgende Bedeutung:
- Core
enthält alle Basisklassen der Business Logic und außerdem Import- und Exportfunktionalität. Aktuell wird die main.cpp verwendet um schnell neue Funktionen zu testen. - Editor
ein grafisches User Interface, welches mit den Basisklassen aus dem Core arbeiten soll. - Tests
Unit Tests für Klassen aus dem Core.
Aus dieser Auflistung wird ersichtlich, dass das Core Projekt keine Anwendung (.exe) bauen sollte. Vielmehr sollte das Ergebnis eine Bibliothek sein, welche in weiteren Projekten verwendet werden kann. Beispiele dafür sind das bereits beschriebene Projekt Editor, eine grafisches Programm, über das ein Anwender Daten bearbeiten kann und ein Testprojekt um die Bibliothek automatisiert mit Unit Tests fehlerfrei zu halten.
LIB statt EXE
Bei einem neuen Projekt wählt man ein Template für eine statische Bibliothek, man kann aber auch über die Projekteinstellungen ein Projekt einer EXE Datei im Nachhinein ändern. Das funktioniert so:
Der Konfigurationstyp wird von „Anwendung (.exe)“ auf „Statische Bibliothek (.lib)“ geändert. Baut man das Projekt nun erneut, dann findet man im Ausgabeordner nun folgendes Dateien:
Die neu erstellte Core.lib wirkt im Vergleich zum früheren Build der Core.exe Datei gigantisch groß. 2011 KB (EXE) im Vergleich zu 27011 KB (LIB) könnten zu einem Problem werden. Schließlich möchte ich effizienten Code schreiben und nicht den Platz auf der Festplatte unnötig verschwenden. Tatsächlich besteht das Problem nicht einmal in der Debug Version. In meinem Beispielprojekt Game verwende ich die Core.lib und die erstellte EXE ist mit 1799 KB sogar kleiner als die ursprüngliche Core.exe. Das heißt der Linker optimiert den Code.
LIB testen
Um die erstellte Core.lib Datei zu testen habe ich ein neues Projekt Game erstellt und die main.cpp aus dem Core Projekt in das Game Projekt übernommen. Visual Studio zeigt ohne weitere Einstellungen nun zahlreiche Fehler an. Man muss zur Lösung zwei Einstellungen anpassen:
- Include Verzeichnisse
Der Compiler fängt mit den includes nichts an, da die Header in einem anderen Projekt definiert wurden und diese in einem anderen Ordner auf dem Dateisystem liegen. Aus diesem Grund legt man für das Core Projekt mit Hilfe der Variable $(SolutionDir) eine neue Referenz in den Ordner vom Core Projekt an $(SolutionDir)Core. Weiters müssen noch alle externen Include Pfade des Core Projekts hinzugefügt werden wie beispielsweise Boost. - Abhängigkeiten
Das Game Projekt hängt nun vom Core Projekt ab. Ohne dessen Compilat (der LIB Datei) wäre das Erstellen der Anwendung nicht möglich. Man kann das unter den Projekteinstellungen unter Angabe der LIB Datei machen oder unter Visual Studio für eigene Bibliotheken in der gleichen Projektmappe sehr komfortabel mit:
im nun geöffneten „Verweis hinzufügen“ Dialog kann man über eine Checkbox das Core Projekt als Verweis markieren:
Jedesmal wenn man nun das Game Projekt baut wird geprüft ob das Core Projekt aktuell ist und bei Bedarf im Vorfeld die LIB Datei neu erstellt.
Warum LIBs erstellen?
Es gibt folgende Gründe warum man in C++ Projekten gerne Code in LIB Dateien auslagert:
- Modularisierung/Organisation
Es macht Sinn, dass man Code in mehrere Module organisiert. Die Entwicklung eines Monolithen (eine EXE die den gesamten Code des Programms enthält) ist nicht mehr zeitgemäß. Um Vorteile von einer Microservice Architektur zu nutzen sollte man möglichst kleine Module entwickeln, die man einzeln gut testen kann. - Wiederverwendbarkeit
In sich gekapselte Funktionalität lässt sich wieder verwenden. Es kommt nicht selten vor, dass man bestimmte Funktionalität einer bestimmten LIB für das eigene Projekt verwendet. Ich habe eine solche Wiederverwendbarkeit in meinem Projekt geplant. Alle Klassen für Input/Output und die Daten persistieren werden im Core zusammengefasst. Diese Core.lib wird später sowohl vom Editor (exe) als auch vom eigentlichen Programm (exe) verwendet werden.
Alternativen
Neben statischen Bibliotheken (.lib) kann man auch dynamische Bibliotheken (.dll) erstellen. Der Vorteil von statischen Bibliotheken ist jedoch, dass bei der Erstellung des ausführbaren Programms (.exe) der Linker nochmals Optimierungen am Code vornehmen kann. Damit reduziert sich der Code in der EXE auf das Minimum. Es kommen also nur jene Teile der Bibliothek in das Programm, die auch verwendet werden. Ein DLL Projekt muss im Gegensatz dazu die komplette Bibliothek anbieten und kann nicht auf eine spezielle Verwendung hin optimiert werden.
Fazit
In diesem Tutorial habe ich gezeigt wie man unter Visual Studio ein EXE in LIB Projekt ändern kann. Damit erstellt man aus dem Source Code in einem Projekt eine statische Bibliothek die man in anderen Projekten verwenden kann. An einem Beispiel zeigte ich auch noch die Verwendung in der Praxis.