Uruchamianie programu Haskell w systemie operacyjnym Android

216

Uwaga: Jest to rozszerzenie wątku uruchomionego na / r / haskell

Zacznijmy od faktów:

  • Android to niesamowity system operacyjny
  • Haskell to najlepszy język programowania na świecie

Dlatego ich połączenie sprawiłoby, że rozwój Androida byłby znacznie lepszy. Zasadniczo chciałbym tylko wiedzieć, jak pisać programy Haskell dla systemu operacyjnego Android. Moje pytanie brzmi:

Jak mogę uzyskać program Haskell do uruchamiania / uruchamiania w systemie operacyjnym Android?

Robert Massaioli
źródło

Odpowiedzi:

81

To, jak to robisz, polega na uzyskaniu kompilatora Haskell, który może celować w C za pomocą Androida NDK, który jest wyposażony w port GCC dla architektur ARM. JHC może w prosty sposób to zrobić za pomocą bardzo małego pliku inf, który opisuje platformę (rozmiar słowa, kompilator c itp.) Zrobiłem to z zestawem deweloperskim Wii homebrew i było to dość łatwe. Jednak jhc wciąż ma pewne problemy ze stabilnością ze złożonym kodem, takie jak stosowanie stosu transformatora monadowego z IO, ale jhc bardzo się poprawił w ciągu ostatnich 6 miesięcy. W JHC pracuje tylko jedna osoba. Chciałbym, żeby więcej osób mogło mu pomóc.

Inną opcją jest zbudowanie „niezarejestrowanego” portu GHC ukierunkowanego na ndk gcc, jest to o wiele bardziej zaangażowany proces, ponieważ GHC nie jest obecnie prawdziwym kompilatorem krzyżowym i musisz zrozumieć system kompilacji, jakie części potrzebujesz zmiana. Inną opcją jest NHC, która może kompilować krzyżowo do C, np. GHC musisz zbudować nhc ukierunkowane na kompilator C, NHC nie ma wielu rozszerzeń Haskell takich jak GHC.

Gdy kompilator Haskell jest ukierunkowany na NDK GCC, będziesz musiał napisać powiązania albo do szkieletu kodu kleju JD dla Androida NDK (dodany od Androida 2.3), albo musisz napisać kod kleju JNI między Java-C-Haskell, pierwsza opcja jest łatwiejsza rozwiązanie i jeśli dobrze pamiętam, może faktycznie być wstecznie kompatybilny z poprzednimi wersjami Androida poniżej 2.3.

Gdy już to zrobisz, musisz zbudować kod Haskell jako bibliotekę współdzieloną lub bibliotekę statyczną, która zostanie połączona z kodem kleju Java NDK (który sam jest biblioteką współdzieloną). O ile mi wiadomo, oficjalnie nie można uruchamiać natywnych plików wykonywalnych na Androidzie. Prawdopodobnie możesz to zrobić przy użyciu zrootowanego telefonu, więc zakładam, że oznacza to, że nie możesz dystrybuować natywnych plików wykonywalnych w sklepie z aplikacjami, nawet jeśli port gcc NDK może generować natywne pliki wykonywalne w porządku. Prawdopodobnie zabija to również opcję korzystania z LLVM, chyba że można uzyskać JN NDK działający z LLVM.

Największą przeszkodą jest nie tyle uzyskanie kompilatora Haskell dla Androida (co wciąż jest dużą przeszkodą). Największym problemem jest to, że ktoś musi napisać wiążące interfejsy API dla bibliotek NDK, co jest ogromnym zadaniem, a sytuacja jest gorsza, jeśli trzeba napisać kod interfejsu użytkownika systemu Android, ponieważ dla tej części zestawu SDK systemu Android nie ma interfejsów API NDK. Jeśli chcesz zrobić kod interfejsu użytkownika Androida w Haskell, ktoś będzie musiał napisać powiązania Haskell do Javy przez JNI / C. O ile nie istnieje bardziej zautomatyzowany proces pisania bibliotek wiążących (wiem, że istnieją, nie są one dla mnie wystarczająco zautomatyzowane), to szanse, że ktoś to zrobi, są dość małe.

L01man: Czy istnieje poradnik na temat tego, jak to zrobić? W pierwszej części rozumiem, że muszę pobrać JHC. Co mam napisać w pliku inf i jak go używać?

Uwaga: zanim odpowiem na to pytanie, nie używałem jhc od dłuższego czasu, odkąd to napisałem, a nowsze wersje zostały wydane, ponieważ nie wiem, jak stabilny jest jhc, jeśli chodzi o generowanie kodu bardziej złożonych programów Haskell. Jest to ostrzeżenie dla każdego, zanim pomyślisz o stworzeniu dużego programu Haskell z JHC, powinieneś zrobić kilka małych testów, zanim przejdziesz do końca.

jhc ma instrukcję http://repetae.net/computer/jhc/manual.html oraz sekcję dotyczącą konfiguracji kompilacji krzyżowej i pliku .ini z opcjami: http://repetae.net/computer/jhc/manual .html # crosscompilation .

L01man: Druga część jest alternatywą dla pierwszej. Nie wiem jak zrobić to, co powiedziałeś w trzecim.

Zanim zaczniesz, powinieneś mieć trochę wiedzy na temat C i wygodnie posługiwać się interfejsem funkcji obcych Haskell (FFI) i narzędziami takimi jak hs2c. Powinieneś także zapoznać się z używaniem Androida NDK i budowaniem .apk ze współdzielonymi bibliotekami. Musisz je znać, aby połączyć C-Haskell, Java / C-Haskell i opracować programy Haskell dla Androida, które możesz oficjalnie dystrybuować / sprzedawać w sklepie na rynku.

L01man: Rozumiem, że jego celem jest utworzenie powiązania dla interfejsu API Androida. Ale ... czy czwarta część mówi, że nie możemy zrobić .apk z Haskellem?

.apk to tylko format pliku pakietu aplikacji i został zbudowany przy użyciu narzędzi dostarczanych z zestawem Android SDK (nie NDK), nie ma to wiele do zrobienia przy tworzeniu samych plików binarnych. Pakiety Androida mogą zawierać natywne biblioteki współdzielone, tym będzie Twój program Haskell, a natywne biblioteki współdzielone / statyczne są generowane za pośrednictwem Android NDK.

snk_kid
źródło
W żadnym wypadku nie jestem ekspertem od Androida. Ale dziś natknąłem się na tę nową klasę o nazwie NativeACtivity od API poziomu 9 developer.android.com/reference/android/app/NativeActivity.html . Mówią, że można go użyć do implementacji działań wyłącznie w kodzie natywnym. Zastanawiam się, jak trafne / przydatne jest to dla naszych celów? Czy nie oznacza to potrzeby interakcji między Haskell a Javą?
Phil
@Po NativeActivity jest częścią szkieletu kodu kleju NDK dla Androida (Android 2.3), o którym pisałem. Pozwoli ci to napisać cały kod w C / C ++, ale nie będziesz mieć natywnego pliku wykonywalnego, będziesz mieć bibliotekę współdzieloną, która będzie wywoływana z Javy. Jeśli napisałeś powiązania Haskell z NativeActivity, nie musiałbyś pisać powiązań między Javą a Haskellem, ale jak już wspomniałem, interfejsy API NDK stanowią podzbiór pełnych interfejsów API Java, nie ma interfejsów API rodzimych dla standardowego interfejsu użytkownika Androida, na przykład pisać własne w OpenGL (ES) lub pisać powiązania JNI-Haskell.
snk_kid
Czy istnieje poradnik na temat tego, jak to zrobić?
L01man
W pierwszej części rozumiem, że muszę pobrać JHC. Co mam napisać w pliku inf i jak go używać? Druga część jest alternatywą dla pierwszej. Nie wiem jak zrobić to, co powiedziałeś w trzecim. Rozumiem, że jego celem jest utworzenie powiązania dla interfejsu API Androida. Ale ... czy czwarta część mówi, że nie możemy zrobić .apk z Haskellem?
L01man
@ L01man Odpowiedziałem na twoje pytanie w głównej odpowiedzi z powodu limitu znaków w komentarzach.
snk_kid
17

Językiem, który ostatnio zwrócił moją uwagę, jest Eta .

Kompilator Ety to rozwidlenie GHC 7.10, które ma backend JVM. Wygenerowane pliki JAR można wykorzystywać do pisania aplikacji na Androida, a nawet do korzystania z jego interfejsu funkcji zagranicznych do wywoływania rodzimych bibliotek Java Androida.

Brian McKenna napisał post na blogu o tym, jak skonfigurować projekt Android Studio do korzystania z biblioteki Eta .

Robert Massaioli
źródło
16

Istnieje https://github.com/neurocyte/android-haskell-activity demonstrujący działanie Haskellkodu.

gliptak
źródło
4
Syn… kogoś, kto to zrobił! Sława.
Robert Massaioli,
Niedługo przyjrzę się temu bliżej. Jeśli wydaje się to uzasadnione, zmienię zaznaczoną odpowiedź na to pytanie.
Robert Massaioli,
Robert, to wydaje się uzasadnione. Ale wydaje się, że neurocyt nie oferuje szczegółowych instrukcji dotyczących budowy. Przeczytaj github.com/neurocyte/android-haskell-activity/issues/1
gliptak
9

Kiedyś natknąłem się na ten sam wątek Reddit, ale był stary i komentarze były zamknięte. Wysłałem wiadomość do PO, ale nie jestem pewien, czy dotarł do odbiorcy. Moja propozycja tutaj (może działać dla starszych Androidów, gdzie rodzime zajęcia nie były możliwe).

Ja (opracowałem w Haskell jakiś czas temu, ale obecnie przełączyłem się na Smalltalk) obecnie rozwijam port Squeak VM na Androida. Sposób, w jaki to robię, jest podobny do tego, co można rozwiązać w projekcie haskell na Androidzie: kawał kodu C, który należy wywołać z części Java aplikacji (w zasadzie wszystko, co można zrobić w Androidzie, to obsługiwać różne zdarzenia; aplikacja nie może sondować samych zdarzeń i nie ma żadnej pętli zdarzeń). W moim przypadku kod jest generowany przez narzędzia budowlane Squeak VM, w przypadku haskell na Androidzie będzie on generowany z GHC JHC lub dowolnego używanego interfejsu. To repo może być warte obejrzenia:

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

Pod „src” znajduje się kod Java, który zapewnia przechwytywanie zdarzeń użytkownika i wysyłanie ich do kodu natywnego (patrz klasa CogView). Kod C samej maszyny wirtualnej nie istnieje całkowicie (patrz squeakvm.org, gałąź Cog), ale można o tym pomyśleć. Można także zajrzeć pod http://gitorious.org/~golubovsky/cogvm/dmg-blessed/trees/master/platforms/android/vm, który jest nakładką C na interpretera (w tym obsługę zdarzeń użytkownika, pewne mierzenie czasu itp. )

Mam nadzieję że to pomoże.

Dmitry

Dmitry
źródło
6

Myślę, że ogólna odpowiedź powinna pochodzić z transformacji source-> source, ponieważ ładowanie specjalnie skompilowanych współdzielonych obiektów wydaje się być trochę kludge (obejmujące ghc-> c i krok c-> java w powyższych odpowiedziach). Pytanie to mieści się zatem pod nagłówkiem Haskell w JVM, który został wypróbowany (z jednym krokiem jako pośrednia reprezentacja Java) i omówiony szczegółowo . Możesz użyć frege, jeśli skompilujesz tam potrzebne biblioteki. Jedynymi pozostałymi krokami byłyby początki interfejsu API systemu Android przetłumaczonego na akcje IO () i być może opakowanie do zbudowania manifestu xml i apk.

David M. Rogers
źródło
1
W rzeczywistości istnieje prezentacja aplikacji na Androida napisana w Javie i Frege, szczegóły są tutaj groups.google.com/forum
Ingo