在 Android 操作系统上运行 Haskell 程序
Posted
技术标签:
【中文标题】在 Android 操作系统上运行 Haskell 程序【英文标题】:Running a Haskell program on the Android OS 【发布时间】:2011-07-06 07:54:44 【问题描述】:前注:这是在/r/haskell开始的线程的扩展
让我们从事实开始:
android 是一款很棒的操作系统 Haskell 是地球上最好的编程语言因此,很明显,将它们结合起来会使 Android 开发变得更好。所以基本上我只想知道如何为 Android 操作系统编写 Haskell 程序。我的问题是:
如何让 Haskell 程序在 Android 操作系统上执行/运行?
【问题讨论】:
【参考方案1】:最近引起我注意的一种语言是Eta。
Eta 的编译器是 GHC 7.10 的一个分支,它有一个 JVM 后端。可以使用生成的 JAR 文件编写 Android 应用程序,甚至可以使用其 Foreign Function Interface 调用原生 Android Java 库。
Brian McKenna 写了一篇关于 how to configure an Android Studio project to use an Eta library 的博文。
【讨论】:
【参考方案2】:有https://github.com/conscell/hugs-android一个HUGS Haskell解释器到Android的端口。
【讨论】:
【参考方案3】:有https://github.com/neurocyte/android-haskell-activity 演示Haskell
代码正在运行。
【讨论】:
一个……真的有人做到了!荣誉。 我很快就会仔细研究一下。如果它看起来合法,那么我将把标记的答案更改为这个。 罗伯特,它看起来确实是合法的。但是神经细胞似乎没有提供关于构建的详细说明。阅读github.com/neurocyte/android-haskell-activity/issues/1【参考方案4】:我认为一般答案应该来自 source->source 转换,因为加载专门编译的共享对象似乎有点麻烦(在上面的答案中涉及 ghc->c 和 c->java 步骤)。因此,这个问题属于 JVM 上的 Haskell 的标题,它一直是 tried(一步作为 Java 中间表示)和 discussed。如果您需要在那里编译的库,您可以使用frege。剩下的唯一步骤是开始将 Android 框架 API 转换为 IO() 操作,并且可能是用于构建清单 xml 和 apk 的包装器。
【讨论】:
其实有一个用 Java 和 Frege 编写的样板 Android 应用,详情在这里groups.google.com/forum/#!topic/frege-programming-language/…【参考方案5】:如何做到这一点是首先获得一个 Haskell 编译器,该编译器可以使用带有用于 ARM 架构的 GCC 端口的 android NDK 以 C 为目标。 JHC 可以使用描述平台(字长、c 编译器等)的非常小的 inf 样式文件轻松完成此操作。我使用 Wii 自制开发工具包完成了此操作,而且非常简单。然而,jhc 仍然存在一些复杂代码的稳定性问题,例如使用带有 IO 的 monad 转换器堆栈,但 jhc 在过去 6 个月中已经有了很大的改进。只有一个人在为 JHC 工作,我只是希望更多的人可以帮助他。
另一种选择是针对 ndk gcc 构建 GHC 的“未注册”端口,这是一个涉及更多的过程,因为 GHC 目前还不是真正的交叉编译器,您需要了解构建系统的哪些部分你需要改变。另一种选择是 NHC,它可以交叉编译为 C,就像 GHC 你需要构建针对 C 编译器的 nhc,NHC 没有很多像 GHC 这样的 Haskell 扩展。
一旦你有针对 NDK GCC 的 Haskell 编译器,你将需要编写与 android NDK JNI 胶水代码框架(自 android 2.3 起添加)的绑定,或者你必须在 Java-C-Haskell 之间编写 JNI 胶水代码,前一个选项是更简单的解决方案,如果我没记错的话,它实际上可能向后兼容 2.3 以下的早期版本的 Android。
一旦你有了这个,你必须将 Haskell 代码构建为共享库或静态库,并链接到 NDK java 胶水代码(它本身就是一个共享库)。据我所知,您无法在 android 上正式运行本机可执行文件。您可能可以使用有根手机执行此操作,因此我认为这意味着即使 NDK gcc 端口可以很好地生成本机可执行文件,您也无法在应用商店上分发本机可执行文件。这也可能会取消使用 LLVM 的选项,除非您可以让 NDK JNI 与 LLVM 一起使用。
最大的障碍不是为 android 获取 Haskell 编译器(这仍然是一个很大的障碍),最大的问题是有人需要为 NDK 库编写绑定 API,这是一项艰巨的任务,而情况是更糟糕的是,如果您需要编写 android UI 代码,因为 android SDK 的这一部分没有 NDK API。如果您想在 Haskell 中编写 android UI 代码,则必须通过 JNI/C 编写 Haskell 与 Java 的绑定。除非有一个更自动化的过程来编写绑定库(我知道有一些,它们对我来说不够自动化),否则有人这样做的机会非常低。
L01man:有关于如何做到这一点的教程吗?为了 第一部分,我知道我必须下载 JHC。我必须做什么 写入inf文件,如何使用?
请注意,在我回答这个问题之前,我已经有一段时间没有使用 jhc 了,因为我最初编写了这个并且已经发布了更新的版本,所以我不知道 jhc 目前在更复杂的代码生成方面有多稳定Haskell 程序。在考虑使用 JHC 制作大型 Haskell 程序之前,这是对任何人的警告,您应该先做一些小测试,然后再继续。
jhc 确实有一个手册 http://repetae.net/computer/jhc/manual.html 和一个关于设置交叉编译和带有选项的 .ini 文件的部分:http://repetae.net/computer/jhc/manual.html#crosscompilation。
L01man:第二部分是第一部分的替代品。我不知道怎么做你说的 第三个。
在开始之前,您应该对 C 有一定的了解,并熟悉使用 Haskell 外部函数接口 (FFI) 和 hs2c 等工具。您还应该熟悉使用 Android NDK 和使用共享库构建 .apk。您需要了解这些才能在 C-Haskell、Java/C-Haskell 之间进行交互并开发适用于 Android 的 Haskell 程序,您可以在市场商店中正式分发/销售。
L01man:我知道它的目标是为 安卓 API。但是...第 4 部分是否说我们无法制作 .apk 哈斯克尔?
.apk 只是一种应用程序包文件格式,是使用 Android SDK(不是 NDK)附带的工具构建的,这与构建二进制文件本身几乎没有关系。 Android 包可以包含本机共享库,这就是您的 Haskell 程序,并且本机共享/静态库是通过 Android NDK 生成的。
【讨论】:
我绝不是 Android 专家。但是今天我遇到了这个从 API 级别 9 developer.android.com/reference/android/app/NativeActivity.html 开始称为 NativeACtivity 的新类。他们说它可以用于纯粹在本机代码中实现活动。我想知道这对我们的目的有多相关/有用?这是否意味着 Haskell 和 Java 之间不需要交互? @Po NativeActivity 是我一直在写的 android NDK 胶水代码框架 (android 2.3) 的一部分。它将允许您使用 C/C++ 编写所有代码,但您将没有本机可执行文件,您将拥有一个从 Java 调用的共享库。如果您将 Haskell 绑定编写到 NativeActivity,则无需编写 Java 和 Haskell 之间的绑定,但正如我所提到的,NDK API 是完整 Java API 的子集,例如,标准 android UI 没有本机 API在 OpenGL (ES) 中编写自己的或编写 JNI-Haskell 绑定。 是否有关于如何做到这一点的教程? 对于第一部分,我知道我必须下载JHC。我必须在inf文件中写什么以及如何使用它?第二部分是第一部分的替代品。我不知道怎么做你在第三个中所说的。我知道它的目标是为 Android API 创建一个绑定。但是...第四部分是否说我们不能用 Haskell 制作 .apk? @L01man 由于 cmets 中的字符数限制,我已在主要答案中回答了您的问题。【参考方案6】:我曾经遇到过相同的 Reddit 线程,但它很旧,并且 cmets 已关闭。我向 OP 发送了一条消息,但不确定它是否到达了收件人。我在这里的建议(可能适用于无法进行原生活动的旧版 Android)。
我(前段时间在 Haskell 中开发,但目前切换到 Smalltalk)目前正在开发 Squeak VM 到 Android 的端口。我这样做的方式类似于在 haskell-on-android 项目中可能处理的方式:需要从应用程序的 Java 部分调用的 C 代码块(基本上所有可以在 Android 中完成的就是处理各种事件;应用程序本身不能轮询事件并且没有任何事件循环)。在我的情况下,代码是由 Squeak VM 构建工具生成的,在 android 上的 haskell 的情况下,这将从 JHC 的 GHC 或任何使用的前端输出。这个 repo 可能值得一看:
http://gitorious.org/~golubovsky/cogvm/dmg-blessed/trees/master/platforms/android/project
在“src”下是 Java 代码,它提供用户事件拦截并将它们发送到本机代码(参见 CogView 类)。虚拟机本身的 C 代码并不完全存在(参见 squeakvm.org,Cog 分支),但人们可能会明白这一点。还可以查看http://gitorious.org/~golubovsky/cogvm/dmg-blessed/trees/master/platforms/android/vm,它是解释器的 C 前端(包括用户事件处理、一些计时等)
希望这会有所帮助。
德米特里
【讨论】:
以上是关于在 Android 操作系统上运行 Haskell 程序的主要内容,如果未能解决你的问题,请参考以下文章
编写一次并行数组 Haskell 表达式,在 CPU 和 GPU 上运行 repa 并加速
如何在 Haskell 平台中安装具有分析支持的 ghc 和 base
如何在 emacs - haskell 模式下运行 haskell 应用程序?