Ejecutar un programa Haskell en el sistema operativo Android

216

Nota: esta es una extensión del hilo iniciado en / r / haskell

Comencemos con los hechos:

  • Android es un sistema operativo increíble
  • Haskell es el mejor lenguaje de programación del planeta.

Por lo tanto, claramente, combinarlos mejoraría mucho el desarrollo de Android. Esencialmente, me gustaría saber cómo puedo escribir programas Haskell para el sistema operativo Android. Mi pregunta es:

¿Cómo puedo hacer que un programa Haskell se ejecute / ejecute en el sistema operativo Android?

Robert Massaioli
fuente

Respuestas:

81

La forma de hacerlo es obtener primero un compilador Haskell que pueda apuntar a C con el NDK de Android que viene con un puerto GCC para arquitecturas ARM. JHC puede hacer esto trivialmente con un archivo de estilo inf muy pequeño que describe la plataforma (tamaño de palabra, compilador c, etc.) Lo hice con el kit de desarrollo homebrew de Wii y fue bastante fácil. Sin embargo, jhc todavía tiene algunos problemas de estabilidad con el código complejo, como el uso de una pila de transformador de mónada con IO, pero jhc ha mejorado mucho en los últimos 6 meses. Solo hay una persona trabajando en JHC. Solo deseaba que más personas pudieran ayudarlo.

La otra opción es construir un puerto "no registrado" de GHC dirigido al ndk gcc, este es un proceso mucho más complicado porque GHC no es un verdadero compilador cruzado en este momento y necesita comprender el sistema de compilación qué partes necesita cambio. Otra opción es NHC, que puede compilarse de forma cruzada con C, como GHC necesita compilar nhc apuntando a un compilador de C, NHC no tiene muchas extensiones Haskell como GHC.

Una vez que tenga el compilador Haskell dirigido a NDK GCC, deberá escribir enlaces en el marco de código de pegamento JNI de Android NDK (agregado desde Android 2.3) o debe escribir código de pegamento JNI entre Java-C-Haskell, la primera opción es la más fácil solución y si no recuerdo mal, en realidad podría ser compatible con versiones anteriores de Android anteriores a la 2.3.

Una vez que tenga esto, debe compilar el código Haskell como biblioteca compartida o biblioteca estática que se vincula al código de pegamento NDK java (que en sí mismo es una biblioteca compartida). Que yo sepa, no puedes ejecutar oficialmente ejecutables nativos en Android. Probablemente podría hacerlo con un teléfono rooteado, por lo tanto, supongo que esto significa que no puede distribuir ejecutables nativos en la tienda de aplicaciones incluso cuando el puerto NDK gcc puede generar ejecutables nativos muy bien. Esto probablemente también elimina la opción de usar LLVM a menos que pueda hacer que el NDK JNI funcione con LLVM.

El mayor obstáculo no es tanto obtener un compilador Haskell para Android (que sigue siendo un gran obstáculo), el mayor problema es que alguien necesita escribir API vinculantes para bibliotecas NDK, lo cual es una tarea enorme y la situación es peor si usted es necesario escribir el código de la interfaz de usuario de Android porque no hay API NDK para esta parte del SDK de Android. Si desea hacer código de interfaz de usuario de Android en Haskell, alguien tendrá que escribir enlaces de Haskell a Java a través de JNI / C. A menos que haya un proceso más automatizado para escribir bibliotecas vinculantes (sé que hay algunas, simplemente no están lo suficientemente automatizadas para mí), entonces las posibilidades de que alguien lo haga son bastante bajas.

L01man: ¿Hay un tutorial sobre cómo hacer esto? Para la primera parte, entiendo que tengo que descargar JHC. ¿Qué tengo que escribir en el archivo inf y cómo usarlo?

Tenga en cuenta que antes de responder a esta pregunta, no he usado jhc desde hace bastante tiempo desde que escribí esto originalmente y desde entonces se han lanzado versiones más nuevas, por lo que no sé qué tan estable es actualmente jhc cuando se trata de la generación de código de programas Haskell más complejos. Esta es una advertencia para cualquier persona antes de considerar hacer un gran programa Haskell con JHC, debe hacer algunas pruebas pequeñas antes de continuar.

jhc tiene un manual http://repetae.net/computer/jhc/manual.html y una sección sobre configuración de compilación cruzada y archivo .ini con opciones: http://repetae.net/computer/jhc/manual .html # compilación cruzada .

L01man: La segunda parte es una alternativa a la primera. No sé cómo hacer lo que dijiste en el tercero.

Antes de comenzar, debe tener algún conocimiento de C y sentirse cómodo con el uso de la interfaz de funciones externas (FFI) de Haskell y herramientas como hs2c. También debe estar familiarizado con el uso del NDK de Android y la creación de .apk con bibliotecas compartidas. Necesitará conocerlos para interactuar entre C-Haskell, Java / C-Haskell y desarrollar programas de Haskell para Android que pueda distribuir / vender oficialmente en la tienda del mercado.

L01man: Entiendo que su objetivo es crear un enlace para la API de Android. Pero ... ¿la cuarta parte dice que no podemos hacer .apk con Haskell?

.apk es solo un formato de archivo de paquete de aplicación y está construido con las herramientas que vienen con el SDK de Android (no NDK), esto tiene muy poco que ver con la creación de los propios binarios. Los paquetes de Android pueden contener bibliotecas compartidas nativas, esto es lo que será su programa Haskell y las bibliotecas nativas compartidas / estáticas se generan a través del NDK de Android.

revs snk_kid
fuente
De ninguna manera soy un experto en Android. Pero hoy me encontré con esta nueva clase llamada NativeACtivity desde el nivel API developer.android.com/reference/android/app/NativeActivity.html . Dicen que se puede usar para implementar actividades únicamente en código nativo. Me pregunto qué tan relevante / útil es esto para nuestro propósito. ¿Esto implica que no hay necesidad de interacción entre Haskell y Java?
Phil
@Po The NativeActivity es parte del marco de código de pegamento NDK de Android (android 2.3) del que he estado escribiendo. Le permitirá escribir todo su código en C / C ++ pero no tendrá un ejecutable nativo, tendrá una biblioteca compartida a la que se llama desde Java. Si escribió enlaces de Haskell en NativeActivity, no necesitaría escribir enlaces entre Java y Haskell, pero como mencioné, las API de NDK son un subconjunto de las API de Java completas, no hay API nativas para la interfaz de usuario estándar de Android, por ejemplo, tendría para escribir el suyo propio en OpenGL (ES) o escribir enlaces JNI-Haskell.
snk_kid
¿Hay un tutorial sobre cómo hacer esto?
L01man
Para la primera parte, entiendo que tengo que descargar JHC. ¿Qué tengo que escribir en el archivo inf y cómo usarlo? La segunda parte es una alternativa a la primera. No sé cómo hacer lo que dijiste en el tercero. Entiendo que su objetivo es crear un enlace para la API de Android. Pero ... ¿la cuarta parte dice que no podemos hacer .apk con Haskell?
L01man
@ L01man He respondido su pregunta en la respuesta principal debido al límite de caracteres en los comentarios.
snk_kid
16

Hay https://github.com/neurocyte/android-haskell-activity que demuestra el Haskellcódigo en ejecución.

Gliptak
fuente
44
Hijo de ... alguien realmente lo hizo! Prestigio.
Robert Massaioli
Voy a echar un vistazo más de cerca a esto pronto. Si parece legítimo, voy a cambiar la respuesta marcada a esta.
Robert Massaioli
Robert, parece legítimo. Pero los neurocitos no parecen ofrecer instrucciones detalladas sobre la construcción. Lea github.com/neurocyte/android-haskell-activity/issues/1
gliptak el
16

Un lenguaje que me ha llamado la atención recientemente es Eta .

El compilador de Eta es una bifurcación de GHC 7.10 que tiene un back-end JVM. Es posible usar los archivos JAR generados para escribir aplicaciones de Android e incluso usar su interfaz de función externa para llamar a las bibliotecas nativas de Android Java.

Brian McKenna ha escrito una publicación de blog sobre cómo configurar un proyecto de Android Studio para usar una biblioteca Eta .

Robert Massaioli
fuente
9

Una vez me encontré con el mismo hilo de Reddit, pero era viejo y los comentarios estaban cerrados. Envié un mensaje al OP, pero no estoy seguro de si llegó al destinatario. Mi sugerencia aquí (puede funcionar para los androides más viejos donde las actividades nativas no eran posibles).

Yo (desarrollado en Haskell hace algún tiempo, pero actualmente cambié a Smalltalk) actualmente estoy desarrollando un puerto de Squeak VM para Android. La forma en que estoy haciendo esto es similar a lo que podría tratarse en un proyecto de haskell-on-android: un bloque de código C que debe llamarse desde la parte Java de la aplicación (básicamente, todo lo que se puede hacer en Android es manejar varios eventos; una aplicación no puede sondear los eventos en sí misma y no tiene ningún bucle de eventos). En mi caso, el código es generado por las herramientas de construcción Squeak VM, en el caso de haskell en Android, esto se generará desde GHC de JHC o cualquier otro front-end utilizado. Vale la pena ver este repositorio:

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

Bajo "src" está el código Java que proporciona la intercepción de eventos del usuario y los envía al código nativo (vea la clase CogView). El código C de la VM en sí no está completamente allí (vea squeakvm.org, la rama Cog para eso), pero uno puede entender la idea. También se puede buscar en http://gitorious.org/~golubovsky/cogvm/dmg-blessed/trees/master/platforms/android/vm, que es la interfaz C para el intérprete (incluido el manejo de eventos del usuario, algunos horarios, etc. )

Espero que esto ayude.

Dmitry

Dmitry
fuente
6

Creo que la respuesta general debería provenir de las transformaciones source-> source, ya que cargar objetos compartidos especialmente compilados parece ser un poco un error (que involucra ghc-> cy un paso c-> java en las respuestas anteriores). Por lo tanto, esta pregunta cae bajo el encabezado de Haskell en la JVM, que se ha probado (con un paso como una representación intermedia de Java) y se ha discutido en detalle. Puede usar frege si las bibliotecas que necesita compilan allí. Los únicos pasos restantes serían los inicios de la API del marco de Android traducida en acciones IO () y tal vez un contenedor para construir el manifiesto xml y apk.

David M. Rogers
fuente
1
De hecho, existe una aplicación de Android de escaparate escrita en Java y Frege, los detalles están aquí groups.google.com/forum/#!topic/frege-programming-language/…
Ingo