Vorgehensweise bei der Portierung von Linux Software auf MS Windows 11.12.2017 / Niklas Radtke
Unterschiede zwischen Linux und Windows Portierung der Software-Tools Motivation Unterschiede zwischen Linux und Windows Portierung der Software-Tools Portierung der Software-Probleme Fazit/Ausblick
MOTIVATION Momentan: GESI läuft nur unter OpenSUSE 13.1 und SUSE SLED Zielsetzung: GESI soll unter Windows nutzbar sein Dafür muss der taktische Arbeitsplatz unter Windows laufen und eine Kommunikation zum Controller, der auf Linux läuft, bereitstehen VM würde zu große Performanceverluste aufweisen Portierung nötig
Unterschiede zwischen Linux und Windows Portierung der Software-Tools Motivation Unterschiede zwischen Linux und Windows Portierung der Software-Tools Portierung der Software-Problem Fazit/Ausblick
Ausführbares Dateiformat PE-Format (Windows) MS-DOS HEADER MS-DOS STUB SECTION HEADERS PE FILE SIGNATURE PE FILE HEADER PE OPTIONAL HEADER SECTIONS Unterscheidet zwischen ausführbaren Dateien (Images/PE) und Objekt Dateien (COFF Dateien) Images haben gleiche Basis wie COFF Dateien aber zusätzliche Header
Ausführbares Dateiformat PE-Format (Windows) MS-DOS HEADER MS-DOS STUB SECTION HEADERS PE FILE SIGNATURE PE FILE HEADER PE OPTIONAL HEADER SECTIONS Nur bei Images Ersten beiden Header nur zur Kompatibilität zu MS-DOS Gibt eine Fehlermeldung bei Start von MS-DOS aus an
Ausführbares Dateiformat PE-Format (Windows) MS-DOS HEADER MS-DOS STUB SECTION HEADERS PE FILE SIGNATURE PE FILE HEADER PE OPTIONAL HEADER SECTIONS Identifikation des PE-Formats Informationen zur Identifikation der Maschine Enthält windowsspezifische Flags PE Optional Header nur für Images Speichert Ort von import/export Tables
Ausführbares Dateiformat PE-Format (Windows) MS-DOS HEADER MS-DOS STUB SECTION HEADERS PE FILE SIGNATURE PE FILE HEADER PE OPTIONAL HEADER SECTIONS Section Headers zeigen auf Sections Sections sind die Daten Typ im Header definiert
Ausführbares Dateiformat ELF (Linux) Unterscheidet zwischen ausführbaren Dateien und Objekt Dateien Beide beginnen mit einem ELF header und besitzen dann unterschiedliche header tables Nur ELF header an einer festen Position Program header table unterteilt Daten in Segmente (größere Blöcke) Section header table unterteilt in Sektionen (kleinere Blöcke) Unterteilt in drei Kategorien von Objektdateien Relocatable braucht section header table Executable braucht program header table Shared braucht beide header tables
POSIX Linux POSIX = Portable Operating System Interface Gruppe von Standards definiert von IEEE. Ziel: Portabilität von Programmen auf Sourcecode Level unterstützen Definiert zum Beispiel Pfad-Trennung als ‘/’ Definiert auch C Funktionen wie zum Beispiel “mkdir” Damit Windows diese unterstützt muss manchmal “__” vor die Funktion geschrieben werden Windows ist nicht voll POSIX kompatibel
Sockets Linux: Berkley (BSD) Sockets Windows: Winsock Socket ist ein file descriptor und kann deshalb an I/O Funktionen übergeben werden Socket ist kein file descriptor “close” funktioniert bei Sockets "closesocket" Routine muss genutzt werden um Socket zu schließen
Sockets Linux: Berkley (BSD) Sockets Windows: Winsock Socket ist ein file descriptor und kann deshalb an I/O Funktionen übergeben werden Socket ist kein file descriptor “close” funktioniert bei sockets "closesocket" Routine muss genutzt werden um Socket zu schließen Socket Handles sind kleine, nicht negative Zahlen Socket Handles sind Zahlen zwischen Null und INVALID_SOCKET-1
Sockets Linux: Berkley (BSD) Sockets Windows: Winsock Socket ist ein file descriptor und kann deshalb an I/O Funktionen übergeben werden Socket ist kein file descriptor “close” funktioniert bei sockets "closesocket" Routine muss genutzt werden um Socket zu schließen Socket Handles sind kleine, nicht negative Zahlen Socket Handles sind Zahlen zwischen Null und INVALID_SOCKET-1 Raw sockets sind nicht beschränkt und empfangen alle Pakete mit der gleichen Protokollnummer Raw sockets können kein TCP und UDP nur mit einer validen IP-Adresse versenden
Sockets Linux: Berkley (BSD) Sockets Windows: Winsock Socket ist ein file descriptor und kann deshalb an I/O Funktionen übergeben werden Socket ist kein file descriptor “close” funktioniert bei sockets "closesocket" Routine muss genutzt werden um Socket zu schließen Socket Handles sind kleine, nicht negative Zahlen Socket Handles sind Zahlen zwischen Null und INVALID_SOCKET-1 Raw sockets sind nicht beschränkt und empfangen alle Pakete mit der gleichen Protokollnummer Raw sockets können kein TCP und UDP nur mit einer validen IP-Adresse versenden Error codes können mit errno ausgelesen werden Error codes sollten mit WSAGetLastError() ausgelesen werden, die Codes an sich haben im Vergleich zu BSD noch WSA vorne angehängt
Threads Linux: Pthreads Windows: Winthread Besteht aus mehreren Datentypen (pthread_t, pthread_mutex_t, pthread_cond_t etc.) Nur ein Datentyp: HANDLE Signal ist verloren wenn nicht darauf gewartet wird Signal bleibt erhalten bis es zurückgesetzt wird
Unterschiede zwischen Linux und Windows Portierung der Software-Tools Motivation Unterschiede zwischen Linux und Windows Portierung der Software-Tools Portierung der Software-Problem Fazit/Ausblick
Kompiler MSVC Kompiler von Microsoft für Windows Unterstützt firmeneigene Bibliotheken wie MFC und ATL DirectX und GDI+ sind einfach zu nutzen Unterstützung eines Debuggers Portieren erfordert größere Änderungen
Kompiler MinGW Für Windows portierter GCC Relativ langsam Kann die firmeneigenen Bibliotheken von Microsoft nicht benutzen Mit POSIX Kompatibilitätsschicht wie MSYS2 nur wenige Änderungen beim Portieren nötig
Kompiler Fazit Der MSVC würde schneller kompilieren, braucht aber mehr Änderungen Die meisten Vorteile des MSVC fallen beim Portieren weg MinGW wird benutzt, da weniger Änderungen nötig sind
Makefiles Helfen beim Bauen von Software Bauen nur Teile die benötigt sind Beschreiben wie gebaut werden muss Besteht aus Regeln (z.B make install) Wenn kein Parameter angegeben wird, wird die zuerst definierte Regel ausgeführt (in der Regel make all) Regeln können andere Regeln voraussetzen (Abhängigkeiten)
MakeFile GENERIERUNG GNU Build System Generiert Makefiles auf Grundlage einer configure Datei Zielaufruf: “configure && make && make install” Standard Makefiles mit Vorhandensein von bestimmten Regeln Kompiler und flags können mit Umgebungsvariablen gesetzt werden Unterstützt cross-compilation (--build, --target, --host) Ziel für install Regel kann mit --prefix gesetzt werden
Makefile Generation CMake Weiteres Tool zur Generierung von Makefiles von Kitware Basiert auf CMakeLists.txt in jedem Unterverzeichnis des Projektes Unterstützt in-source und out-of-source builds Verschiedene Betriebssystem und Kompiler Kombinationen können mit “–G <Name>” gesetzt werden CMake Funktionen können mit selbstgeschriebenen Modulen erweitert werden
Unterschiede zwischen Linux und Windows Portierung der Software-Tools Motivation Unterschiede zwischen Linux und Windows Portierung der Software-Tools Portierung der Software-Problem Fazit/Ausblick
Probleme bei der Portierung Fehlerhafte Makefiles Fehler bei der Generierung Fehlende Regeln zum Bauen Andere Methode zum Einbinden nutzen (Von Windows oder Version von pacman) Neuer Kompiler und “–Werror” gesetzt Funktionen sind veraltet (deprecated) dadurch entsteht ein Error beim Bauen “-Werror” flag muss aus den Makefiles entfernt werden
Probleme bei der Portierung Pfade in CMake MSYS wandelt gekürzte Linux Pfade automatisch in Windows Pfade um CMake kann das nicht Pfade müssen entweder vollständig übergeben werden oder Linux Pfade innerhalb der CMakeLists.txt müssen geändert werden
Probleme bei der Portierung Hinzugefügte CMakemodule Module müssen von CMake gefunden werden Module in den Suchpfad für CMakemodule kopieren Oder Modulpfad mit „LIST(APPEND Cmake_MODULE_PATH <Pfad>)“ dem Suchpfad hinzufügen
Probleme bei der Portierung Finden von Bibliotheken Bibliotheken werden nicht gefunden Pfad zur nicht gefundenen Bibliothek mit “-L<Pfad>” zu den Suchpfaden hinzufügen
Probleme bei der Portierung Fehlende Linker Flags in den Makefiles Bibliotheken werden nicht gelinkt Reihenfolge der Flags wichtig Undefined references können entstehen Fehlende Linker Flags mit “-l” hinzufügen Benötigte Flags immer hinter denen schreiben, die diese brauchen
Probleme bei der Portierung Undefined References Treten auf wenn der Kompiler die Deklaration einer Funktion nicht finden kann Kann passieren wenn nicht alles richtig gelinkt ist __gxx_personality_v0: C++ Code wird mit einem C-Kompiler kompiliert Auf C++-Kompiler wechseln oder “-lstdc++” linken _imp__inet_addr: Socket library nicht richtig gelinkt Sicherstellen das “Winsock” gefunden und gelinkt wird
Probleme bei der Portierung Lizensierte Bibliotheken Lizensierte Bibliothek kann nur unter Linux benutzt werden Funktionen der Bibliothek selber implementieren Software so umschreiben, dass die Bibliothek nicht benötigt wird
Probleme bei der Portierung Nicht existierende Includes Manche Header existieren nicht unter Windows, die Funktionalität aber schon Wrapper mit dem Namen des Linux Headers, der die Funktionen auf die Windows Routinen ändert.
Probleme bei der Portierung Gleiche Deklarationen #include <windows.h> // #define rad2 0x002 in windows.h #undef rad2 namespace windowsHeader{ class Polygon{}; } namespace source{ int main(){ source::Polygon rad2; return 1; Windows Header definieren Namen, die Linux Header nicht definieren Name wurde schon mit #define definiert Definition muss mit #undef rückgängig gemacht werden Klasse mit demselben Namen existiert schon Vollständigen namespace angeben
Probleme bei der Portierung Funktionen in Windows nicht benutzbar Header definieren nicht die gleichen Funktionen Funktion kann ersetzt werden: Funktion als Wrapper implementieren oder Funktion durch andere ersetzen Funktion kann nicht ersetzt werden: Code muss analysiert werden und Funktion mit vorhandenen Funktionen implementiert werden
Probleme bei der Portierung Dateien nicht kompatibel mit Windows Datei prüft ob das Betriebssystem Linux ist Kann in Cmake und Quelldateien vorkommen Prüfung muss entfernt oder umgeschrieben werden
Probleme bei der Portierung Dependencies Bibliotheken können andere benötigen Können erst gebaut werden, wenn alle Benötigten gebaut worden sind Zeitverzögerung wenn bei einer Basisbibliothek viele Probleme auftreten
Probleme bei der Portierung Dependencies xerces rapidxml rapidjson python qt QtSolutions osgearth libtiff libkml gmock geos boost libavro antlr protobuf jasper proj4 OpenSceneGraph libgeotiff gdal Library Dependency
Unterschiede zwischen Linux und Windows Portierung der Software-Tools Motivation Unterschiede zwischen Linux und Windows Portierung der Software-Tools Portierung der Software-Problem Fazit/Ausblick
Fazit/Ausblick Um GESI auf Windows zu nutzen muss es portiert werden Teile der benötigten Bibliotheken und des Codes müssen geändert werden Kommunikation zwischen dem taktischen Arbeitsplatz auf Windows und dem Controller, der auf Linux läuft, muss untersucht werden
Fragen?
Quelllen POSIX: http://pubs.opengroup.org/onlinepubs/9699919799/ nfindex.html ELF Format: https://docs.oracle.com/cd/E23824_01/html/819- 0690/chapter6-46512.html#scrolltoc PE Format: https://msdn.microsoft.com/en- us/library/windows/desktop/ms680547(v=vs.85).as px Surueña. ELF Structure: https://en.wikipedia.org/wiki/File:Elf-layout--en.svg Lizensiert unter GNU Free Documentation License Port Socket applications to Windows: https://msdn.microsoft.com/en- us/library/windows/desktop/ms740096(v=vs.85).as px Cmake: https://CMake.org/ Raw Socket in Linux: https://manpages.debian.org/stretch/manpages/ra w.7.en.html Threads in Linux: http://pubs.opengroup.org/onlinepubs/9699919799/ functions/V2_chap02.html#tag_15_09 Threads in Windows: https://msdn.microsoft.com/en- us/library/windows/desktop/ms681917(v=vs.85).as px Makefiles: https://www.gnu.org/software/make/manual/make.h tml GNU Build System: https://www.gnu.org/software/automake/manual/au tomake.html
Thank you!