Ausführen eines Haskell-Programms unter Android

216

Vorbemerkung: Dies ist eine Erweiterung des Threads, der auf / r / haskell gestartet wurde

Beginnen wir mit den Fakten:

  • Android ist ein fantastisches Betriebssystem
  • Haskell ist die beste Programmiersprache der Welt

Daher würde eine Kombination diese Android-Entwicklung deutlich verbessern. Im Wesentlichen möchte ich nur wissen, wie ich Haskell-Programme für das Android-Betriebssystem schreiben kann. Meine Frage ist:

Wie kann ich ein Haskell-Programm unter Android ausführen lassen?

Robert Massaioli
quelle

Antworten:

81

Dazu erhalten Sie zunächst einen Haskell-Compiler, der mit dem Android-NDK, das über einen GCC-Port für ARM-Architekturen verfügt, auf C abzielen kann. JHC kann dies trivial mit einer sehr kleinen Datei im Inf-Stil tun, die die Plattform beschreibt (Wortgröße, C-Compiler usw.). Ich habe dies mit dem Wii-Homebrew-Entwicklungskit gemacht und es war ziemlich einfach. Allerdings hat jhc immer noch einige Stabilitätsprobleme mit komplexem Code, wie die Verwendung eines Monadentransformatorstapels mit E / A, aber jhc hat sich in den letzten 6 Monaten stark verbessert. Es gibt nur eine Person, die an JHC arbeitet. Ich wünschte nur, mehr Menschen könnten ihm helfen.

Die andere Möglichkeit besteht darin, einen "nicht registrierten" GHC-Port zu erstellen, der auf das ndk gcc abzielt. Dies ist ein viel komplizierterer Prozess, da GHC derzeit kein echter Cross-Compiler ist und Sie das Build-System verstehen müssen, welche Teile Sie benötigen Veränderung. Eine weitere Option ist NHC, das mit C überkompiliert werden kann. Wie GHC müssen Sie nhc für einen C-Compiler erstellen. NHC verfügt nicht über viele Haskell-Erweiterungen wie GHC.

Sobald Sie einen Haskell-Compiler haben, der auf NDK GCC abzielt, müssen Sie Bindungen entweder an das Android NDK JNI-Klebercode-Framework (hinzugefügt seit Android 2.3) schreiben oder JNI-Klebercode zwischen Java-C-Haskell schreiben. Die erstere Option ist die einfachere Lösung und wenn ich mich richtig erinnere, könnte tatsächlich abwärtskompatibel mit früheren Versionen von Android unter 2.3 sein.

Sobald Sie dies haben, müssen Sie Haskell-Code als gemeinsam genutzte Bibliothek oder statische Bibliothek erstellen, die mit dem NDK-Java-Klebercode (der selbst eine gemeinsam genutzte Bibliothek ist) verknüpft wird. Soweit mir bekannt ist, können Sie native ausführbare Dateien auf Android nicht offiziell ausführen. Sie könnten dies wahrscheinlich mit einem gerooteten Telefon tun, daher gehe ich davon aus, dass Sie keine nativen ausführbaren Dateien im App Store verteilen können, selbst wenn der NDK-gcc-Port native ausführbare Dateien problemlos generieren kann. Dies macht wahrscheinlich auch die Option für die Verwendung von LLVM zunichte, es sei denn, Sie können das NDK-JNI mit LLVM arbeiten lassen.

Die größte Hürde besteht nicht darin, einen Haskell-Compiler für Android zu bekommen (was immer noch eine große Hürde ist). Das größte Problem ist, dass jemand Bindungs-APIs für NDK-Bibliotheken schreiben muss, was eine große Aufgabe ist und die Situation schlimmer ist, wenn Sie Ich muss Android-UI-Code schreiben, da es für diesen Teil des Android-SDK keine NDK-APIs gibt. Wenn Sie Android-UI-Code in Haskell erstellen möchten, muss jemand Haskell-Bindungen über JNI / C an Java schreiben. Wenn das Schreiben von Bindungsbibliotheken nicht automatisierter ist (ich weiß, dass es einige gibt, sie sind für mich einfach nicht automatisiert genug), sind die Chancen, dass jemand dies tut, recht gering.

L01man: Gibt es ein Tutorial dazu? Für den ersten Teil verstehe ich, dass ich JHC herunterladen muss. Was muss ich in die inf-Datei schreiben und wie benutze ich sie?

Bitte beachten Sie, bevor ich diese Frage beantworte, dass ich jhc seit einiger Zeit nicht mehr verwendet habe, seit ich dies ursprünglich geschrieben habe. Seitdem wurden neuere Versionen veröffentlicht, sodass ich nicht weiß, wie stabil jhc derzeit ist, wenn es um die Codegenerierung komplexerer Haskell-Programme geht. Dies ist eine Warnung für alle, bevor Sie überlegen, ein großes Haskell-Programm mit JHC zu erstellen. Sie sollten einige kleine Tests durchführen, bevor Sie fortfahren.

jhc verfügt über ein Handbuch http://repetae.net/computer/jhc/manual.html und einen Abschnitt zum Einrichten der Cross-Compilation- und INI-Datei mit den folgenden Optionen: http://repetae.net/computer/jhc/manual .html # Crosscompilation .

L01man: Der zweite Teil ist eine Alternative zum ersten. Ich weiß nicht, wie ich das tun soll, was du im dritten gesagt hast.

Bevor Sie beginnen, sollten Sie über Kenntnisse in C verfügen und mit der Verwendung der Haskell Foreign Function Interface (FFI) und Tools wie hs2c vertraut sein. Sie sollten auch mit der Verwendung des Android NDK und dem Erstellen von .apk mit gemeinsam genutzten Bibliotheken vertraut sein. Sie müssen diese kennen, um eine Schnittstelle zwischen C-Haskell, Java / C-Haskell herzustellen und Haskell-Programme für Android zu entwickeln, die Sie offiziell im Market Store vertreiben / verkaufen können.

L01man: Ich verstehe, dass das Ziel darin besteht, eine Bindung für die Android-API zu erstellen. Aber ... sagt der 4. Teil, dass wir mit Haskell kein .apk machen können?

.apk ist nur ein App-Paket-Dateiformat und basiert auf den Tools, die mit dem Android SDK (nicht NDK) geliefert werden. Dies hat sehr wenig mit dem Erstellen der Binärdateien selbst zu tun. Android-Pakete können native gemeinsam genutzte Bibliotheken enthalten. Dies ist das, was Ihr Haskell-Programm sein wird, und die nativen gemeinsam genutzten / statischen Bibliotheken werden über das Android-NDK generiert.

snk_kid
quelle
Ich bin kein Android-Experte. Aber heute bin ich auf diese neue Klasse namens NativeACtivity gestoßen, seit API Level 9 developer.android.com/reference/android/app/NativeActivity.html . Sie sagen, dass es für die Implementierung von Aktivitäten rein in nativem Code verwendet werden kann. Ich frage mich, wie relevant / nützlich dies für unseren Zweck ist. Bedeutet dies, dass keine Interaktion zwischen Haskell und Java erforderlich ist?
Phil
@Po Die NativeActivity ist Teil des Android NDK-Klebercode-Frameworks (Android 2.3), über das ich geschrieben habe. Damit können Sie Ihren gesamten Code in C / C ++ schreiben, aber Sie haben keine native ausführbare Datei, sondern eine gemeinsam genutzte Bibliothek, die von Java aufgerufen wird. Wenn Sie Haskell-Bindungen an NativeActivity geschrieben haben, müssen Sie keine Bindungen zwischen Java und Haskell schreiben. Wie bereits erwähnt, sind die NDK-APIs Teilmengen der vollständigen Java-APIs. Es gibt jedoch keine nativen APIs für die Standard-Android-Benutzeroberfläche um eigene in OpenGL (ES) zu schreiben oder JNI-Haskell-Bindungen zu schreiben.
snk_kid
Gibt es ein Tutorial dazu?
L01man
Für den ersten Teil verstehe ich, dass ich JHC herunterladen muss. Was muss ich in die inf-Datei schreiben und wie benutze ich sie? Der zweite Teil ist eine Alternative zum ersten. Ich weiß nicht, wie ich das tun soll, was du im dritten gesagt hast. Ich verstehe, dass sein Ziel darin besteht, eine Bindung für die Android-API zu erstellen. Aber ... sagt der 4. Teil, dass wir mit Haskell kein .apk machen können?
L01man
@ L01man Ich habe Ihre Frage in der Hauptantwort wegen der Zeichenbeschränkung in den Kommentaren beantwortet.
snk_kid
16

Unter https://github.com/neurocyte/android-haskell-activity wird die HaskellAusführung von Code demonstriert .

Gliptak
quelle
4
Sohn eines ... jemand hat es tatsächlich getan! Ein großes Lob.
Robert Massaioli
Ich werde mir das bald genauer ansehen. Wenn es legitim erscheint, werde ich die markierte Antwort auf diese ändern.
Robert Massaioli
Robert, es scheint echt zu sein. Aber Neurozyten scheinen keine detaillierten Anweisungen zum Aufbau zu bieten. Lesen Sie github.com/neurocyte/android-haskell-activity/issues/1
gliptak
16

Eine Sprache, auf die ich kürzlich aufmerksam geworden bin, ist Eta .

Der Compiler von Eta ist ein Fork von GHC 7.10 mit einem JVM-Backend. Es ist möglich, die generierten JAR-Dateien zum Schreiben von Android-Apps zu verwenden und sogar über die Fremdfunktionsschnittstelle native Android-Java-Bibliotheken aufzurufen.

Brian McKenna hat einen Blog-Beitrag darüber geschrieben, wie ein Android Studio-Projekt für die Verwendung einer Eta-Bibliothek konfiguriert wird .

Robert Massaioli
quelle
9

Ich bin einmal auf denselben Reddit-Thread gestoßen, aber er war alt und die Kommentare wurden geschlossen. Ich habe eine Nachricht an das OP gesendet, bin mir aber nicht sicher, ob sie den Empfänger erreicht hat. Mein Vorschlag hier (funktioniert möglicherweise bei älteren Androiden, bei denen einheimische Aktivitäten nicht möglich waren).

Ich (vor einiger Zeit in Haskell entwickelt, aber derzeit auf Smalltalk umgestellt) entwickle derzeit eine Portierung von Squeak VM auf Android. Die Art und Weise, wie ich das mache, ähnelt der, die in einem Haskell-on-Android-Projekt behandelt werden könnte: Ein Klumpen C-Code, der aus dem Java-Teil der Anwendung aufgerufen werden muss (im Grunde ist alles, was in Android getan werden kann, zu verschiedene Ereignisse behandeln; eine Anwendung kann nicht nach Ereignissen selbst abfragen und hat keine Ereignisschleife). In meinem Fall wird der Code von den Squeak VM-Erstellungstools generiert. Im Fall von Haskell auf Android wird dieser von GHC von JHC oder einem anderen verwendeten Front-End ausgegeben. Dieses Repo kann einen Blick wert sein:

http://gitorious.org/~golubovsky/cogvm/dmg-blessed/trees/master/platforms/android/project

Unter "src" befindet sich der Java-Code, mit dem Benutzerereignisse abgefangen und an den nativen Code gesendet werden können (siehe CogView-Klasse). Der C-Code der VM selbst ist nicht vollständig vorhanden (siehe squeakvm.org, der Cog-Zweig dafür), aber man kann auf die Idee kommen. Man könnte auch unter http://gitorious.org/~golubovsky/cogvm/dmg-blessed/trees/master/platforms/android/vm nachsehen welches das C-Frontend für den Interpreter ist (einschließlich der Behandlung von Benutzerereignissen, einiger Zeitmessung usw.). )

Hoffe das hilft.

Dmitry

Dmitry
quelle
6

Ich denke, die allgemeine Antwort sollte von Quell-> Quellentransformationen stammen, da das Laden speziell kompilierter gemeinsam genutzter Objekte ein bisschen klobig zu sein scheint (mit ghc-> c und einem c-> Java-Schritt in den obigen Antworten). Diese Frage fällt daher unter die Überschrift von Haskell in der JVM, die (mit einem Schritt als Java-Zwischendarstellung) ausprobiert und ausführlich diskutiert wurde . Sie können frege verwenden, wenn die benötigten Bibliotheken dort kompiliert werden. Die einzigen verbleibenden Schritte wären die Anfänge der Android-Framework-API, die in IO () -Aktionen übersetzt wurden, und möglicherweise ein Wrapper zum Erstellen des Manifests xml und apk.

David M. Rogers
quelle
1
Tatsächlich gibt es eine in Java und Frege geschriebene Showcase-Android-App. Details finden Sie hier groups.google.com/forum/#!topic/frege-programming-language/…
Ingo