Visual Studio Linux Remote Entwicklung
In meinem Raspberry Pi als Visual Studio Linux Remotesystem Artikel habe ich euch gezeigt, dass man mit Visual Studio am Windows Rechner Linux Programme auf einem entfernten System entwickeln kann. Beim ersten großen Projekt stößt man auf einige Probleme…alles darüber wie man diese löst.
Visual Studio Linux Remote Entwicklung
Bei einem C++ Projekt kommt man selten ohne externe Bibliotheken aus. Heute gibt es viele Funktionalitäten bereits fertig entwickelt, man muss nicht immer alles neu erfinden. Einige Beispiele:
- MySQL Connector
- Json Bibliothek
- XML Bibliothek
- Grafikschnittstellen wie DirectX oder Open GL
- …
Ohne diese fertigen Schnittstellen und Bibliotheken würde die Entwicklungszeit für ein Projekt drastisch steigen. Doch wie verwendet man ein externe Bibliothek. Muss man diese am Windows System auf dem Visual Studio läuft einbinden oder auf dem Linux System?
Datei oder Verzeichnis nicht gefunden
Ich habe ein fertiges C++ Projekt, dass einige externe Bibliotheken für MySQL, Json und XML einbindet und unter Windows und Visual Studio kompiliert. Nun möchte ich das aber auch für Linux bauen – es soll später auf einem Linux Server als API laufen. Ich erstelle also ein neues Linux Remote Projekt und füge alle existierenden Quelldateien hinzu. Außerdem übernehme ich alle Projektoptionen (Include Pfade, Linker Pfade usw.). Das Projekt lässt sich auf dem Linux System nicht kompilieren:
Auf dem Screenshot des Compiler Outputs sieht man, dass jede externe Include Datei nicht gefunden wird. Die Meldung:
Datei oder Verzeichnis nicht gefunden
compilation terminated
wird für jede fehlende externe Header Datei einmal ausgegeben.
Externe Bibliotheken richtig einbinden
Ein Vergleich der Visual Studio Projektoptionen zeigt, dass es im Linux Projekt weniger Punkte gibt. Außerdem sind alle Einstellungen unter VC++-Verzeichnisse leer. Genau dort müssen wir aber die Pfade zu den externen Header Dateien angeben. Was nicht funktioniert sind die Pfade des Windows Rechners:
Kompiliert man nun neu, ändert sich genau gar nichts. Die Header werden immer noch nicht gefunden. Der Grund ist ganz einfach – Der Source Code wird auf den Linux Rechner kopiert und dort kompiliert. Auf dem Linux Server gibt es die Pfade C:\ nicht. Dort sind die Bibliotheken nicht installiert und Visual Studio kopiert diese nicht automatisch mit. Wir müssen deshalb auf dem Linux System nun diese Bibliotheken ebenfalls installieren, in den Einstellungen des Projekts muss man die Pfade zu diesen mit den Pfaden am entfernten Linux System tauschen. Das sieht bei mir so aus:
Zur Erinnerung: Visual Studio verbindet sich mit dem Linux Rechner über SSH mit einem Benutzerkonto. Standardmäßig landet man dort im Home Verzeichnis des Benutzers und genau dort legt Visual Studio einen projects Ordner an. Dort habe ich alle meine Bibliotheken hin kopiert und gegebenenfalls erstellt (make). Die Einstellungen unter Windows mit Linux Pfaden sehen irgendwie falsch aus, kompiliert man nun aber erneut, dann werden keine Fehler mehr ausgegeben.
Linker Fehler
Ok, keine Fehler war nicht ganz die Wahrheit. Der Compiler wirft keine Fehler mehr. Der Linker schon. das ist auch klar, denn neben den Pfaden zu den Header Dateien müssen wir nun auch die Pfade zu den kompilierten Bibliotheken auf dem Linux System angeben:
Der Linker gibt pro fehlender Information zu einer Funktion die aus einer Bibliothek aufgerufen werden soll eine Fehlermeldung und der Form:
error: In Funktion …
error: Nicht definierter Verweis auf …
aus. Diese Meldungen kommen aus dem kompilierten Objekt (*.o Datei) und aus der Quelldatei (*.cpp Datei). Ein kurzer Blick auf des Linux Remote System zeigt, dass zum Beispiel für den MySQL Connector die Bibliotheksdateien im lib Ordner bereits vorhanden sind. Andere Bibliotheken die man beispielsweise von GitHub zieht haben eventuell diese vorkompilierten Bibliotheken noch nicht und müssen erst mit make erstellt werden.
Unter Linux gibt es nicht wie unter Windows *.lib und *.dll Dateien, dort heißen diese Bibliotheken *.so beziehungsweise *.a. Es ist nun recht einfach in den VC++-Verzeichnisse in den Visual Studio Projekteinstellungen unter Bibliotheksverzeichnisse die Pfade zu diesen Bibliotheken zu setzen. Zusätzlich zu den Pfaden muss man auch die Bibliotheken mit dem Namen ansprechen. Es reicht den Namen der Bibliothek unter Linker -> Eingabe -> Bibliotheksabhängigkeiten zu definieren (mit ; getrennt falls man mehr als eine Bibliothek verwendet). Wie ihr seht reicht der Name, der Linker fügt selbstständig lib davor beziehungsweise -static.a oder -.so hinzu.
Achtung: genau wie unter Windows auch müsst ihr unter Debug und Release Versionen unterscheiden, denn sonst kann man eventuell nicht linken oder unter der Debug Version nicht ordentlich debuggen. Die Projekte bei denen man die Bibliotheken selbst erstellen muss sind oft besser geeignet, da man dort zwischen Debug und Release unterscheiden kann. Der oben erwähnte MySQL Connector für C++ kommt nur mit vorkompilierten Dateien der Release Version – man kann dort also nicht rein debuggen.
Probleme
Beim Kompilieren kommt leider nun immer noch ein Fehler. Mehrere Objekte melden:
‚.rodata‘ can not be used when making a PIE object; recompile with -fPIC
Tja keine Ahnung was das bedeuten soll. Nach längerer Recherche habe ich herausgefunden, dass offenbar standardmäßig ein PIE Objekt erstellt wird. Man löst das mit der -no-pie Option.
Damit klapp es dann endlich mit der ausführbaren Datei unter Linux.
Fazit
Einstellen der Linux Remote Verzeichnisse für Header und Bibliotheken externer Abhängigkeiten ist sogar noch etwas mühsamer als bei einem rein Windows Projekt. In diesem Artikel habe ich euch gezeigt wie man das für ein etwas komplexeres Projekt macht. Man muss die Bibliotheken unter Linux installieren und alle Pfade unter Visual Studio für den entfernten Entwicklungsserver anpassen. Das erste Mal ist sehr nervig. Einmal korrekt eingestellt läuft das aber danach problemlos.
Was entwickelt ihr so unter Linux? Welche externen Bibliotheken sind zu empfehlen?
Ich will einen CarPC mit dem PI bauen. Der von dir Vorgestellt weg mag gehen wenn man nicht so oft bauen weil wie zum Beispiel den Code schon unter Windows am laufen hat. Wenn jedoch die Remotemachine der PI ist wird das lästig. Weil c++ Compilieren auf dem PI macht nicht wirklich Spaß wenn es mal mehr als 5 Zeilen sind. Auf der Anderen Seite muss man sagen Resharper und Visual Studio machen das Leben hat furchtbar einfach. Ich bin in der glücklichen Lage Resharper in der großen Lizenz nutzen zu dürfen so das ich auch im C++ Code was davon habe.
Leider halt nicht im CarPC Projekt..