|
|
## Linux
|
|
|
|
|
|
Üblicherweise lassen sich Haskell-Programme einfach statisch linken, um sie dann als Binary verteilen zu können. Bei DrHaskell funktioniert das nicht so einfach:
|
|
|
|
|
|
- Um statisch linken zu können, werden die statischen Bibliotheken benötigt (momentan libffi, libgmp und libncursesw, letzteres durch Haskeline), die oft zusätzlich nachinstalliert werden müssen (Gentoo: mit `USE="static-libs"`, Debian-Derivate: `*-dev`-Pakete installieren)
|
|
|
- Wir verwenden als Interpreter Hint, das wiederum nur ein hübsches Interface für die GHC-Bibliothek ist. Während sich die GHC-Bibliotheken zwar statisch linken lassen, versuchen sie, per `dlopen` weitere Bibliotheken zur Laufzeit nachzuladen. Diese müssen entsprechend mitgeliefert werden.
|
|
|
|
|
|
#### Notwendige Schritte zum Bauen eines Standalone Releases
|
|
|
|
|
|
1. Anstatt sich die GHC-Bibliotheken aus dem eigenen System zusammenzukratzen und eventuell für die Distribution gepatchte Pakete zu benutzen, kompilieren wir zunächst einen Vanilla-GHC aus den Mainline-Quellen. Wir installieren ihn nicht, da wir ohnehin eine eigene Ordnerstruktur erhalten werden.
|
|
|
2. Wir installieren alle Abhängigkeiten für DrHaskell in eine neue Sandbox, dabei nutzen wir den eben gebauten GCH *inplace*.
|
|
|
3. Wir nutzen ebenfalls diesen GHC, um damit DrHaskell wie gewohnt per Cabal zu bauen. Wir kompilieren *nicht* statisch, Erklärung dafür folgt später
|
|
|
4. Wir stellen unser DrHaskell-Paket zusammen und nehmen dafür die im folgenden beschriebenen Dateien. Die genaue Zielstruktur wird noch erarbeitet.
|
|
|
5. Wir verpacken das Paket in ein Archiv
|
|
|
|
|
|
#### Notwendige Dateien
|
|
|
|
|
|
- Unsere Binaries, `drhaskell` und `drhaskell-lint`, offensichtlich
|
|
|
- Die Bibliotheken libffi, libgmp, libncursesw als *.so-Datei und aller zugehörigen Symlinks
|
|
|
- Den GHC/inplace/lib-Ordner
|
|
|
- Teile (welche Teile wird noch herausgearbeitet) des GHC/libraries-Ordners
|
|
|
|
|
|
#### Offene Probleme
|
|
|
|
|
|
- Standardmäßig werden keine Bibliotheken aus dem aktuellen (oder einem Unter-)Pfad geladen. Zur Not ließe sich dies mit einem Wrapperskript und der Environmentvariable `LD_LIBRARY_PATH` erreichen, besser wäre es aber, wenn wir einen `rpath` oder `runpath` in unsere Binaries bekämen. Wahrscheinlich lässt sich dies durch GHC-Optionen, die man im Cabal-Aufruf angibt, beim Kompilieren in die Binaries bekommen. Ansonsten existieren auch Programme, die die erzeugten ELF-Dateien entsprechend ändern können.
|
|
|
- Die GHC-Bibliotheken werden zurzeit an dem Pfad gesucht, wo sie zur Compilezeit lagen. Das ist auch korrekt, wenn DrHaskell per Cabal installiert wird. Für unseren Standalone-Build muss dieser Pfad allerdings relativ zur Binary gesucht werden. Der Code muss sich also im üblichen Cabal-Build und in unserem Standalone-Build unterscheiden. Vielleicht lässt sich `cpphs` hierfür einsetzen.
|
|
|
- Der Ordner GHC/inplace/lib/ enthält eine Paketdatenbank, die absolute Pfade enthält. Diese müssen angepasst werden. Da diese allerdings Plaintext sind, lässt sich dies leicht z.B. mit einem Bashskript und `sed` bewerkstelligen. Dies muss am Zielort geschehen, beispielsweise beim Start der Repl.
|
|
|
- In diesem Ordner ist ebenfalls ein Paketcache in einem Binärformat. Dieser kann allerdings gelöscht und mit `ghc-pkg recache` mit den neuen Pfaden neu erzeugt werden.
|
|
|
- ...
|
|
|
|
|
|
|
|
|
#### Kein statisches Linken
|
|
|
|
|
|
Wir können die Binaries nicht statisch linken, da diese per `dlopen` weitere Bibliotheken nachladen. Diese nachgeladenen Bibliotheken benötigen jedoch selbst wiederum Symbole, die in unseren Binaries liegen. Wenn wir unsere Binaries statisch kompilieren, werden diese jedoch nicht exportiert, sodass das Laden der zusätzlichen Bibliotheken mit einem *Missing Symbol*-Fehler abbricht. Linken wir unsere Binaries dynamisch, so kann der Linker diese Symbole aus dem Binary exportieren, sodass die Bibliothek diese sehen und nutzen kann. Allerdings müssen wir auch andere C-Bibliotheken als shared objects mitliefern.
|
|
|
|
|
|
#### Funktioniert aber ist etwas unschön
|
|
|
|
|
|
- Die Notwendigkeit absoluter Pfade macht es nötig, Dateien auf dem Zielsystem anzupassen.
|
|
|
- Das DrHaskell-Paket wird riesig. \*.tar.gz mit Kompressionsstufe 9: gut 200MB, Ausgepackt auf Zielsystem: gut 2GB
|
|
|
|
|
|
|
|
|
## Windows
|
|
|
|
|
|
Wahrscheinlich ist die Prozedur sehr ähnlich (cygwin?). Allerdings ist werden unter Windows wohl standardmäßig Pfade relativ zum Binary für die Paketdatenbank verwendet, sodass wir hier wahrscheinlich die Pfadanpassungen sparen können.
|
|
|
|
|
|
Vielleicht ist sogar Cross-Compiling von einem Linuxsystem aus möglich. Das würde die Entwicklung vereinfachen.
|
|
|
|
|
|
**`TODO`**
|
|
|
|
|
|
## Mac OS
|
|
|
|
|
|
**`TODO`** |
|
|
\ No newline at end of file |