我用 Haskell 编写了一个应用程序,它开始对用户有点用处。然而,我的应用程序并不针对技术熟练的人,更不用说 Haskell 开发人员了,所以从源代码构建我的应用程序并不是我可以期望他们做的事情。
因此,为了让我的用户可以使用我的应用程序,我想自己构建应用程序,将其可执行文件、数据文件、依赖项、依赖项的数据文件、所需的许可信息和其他所需文件放入一个存档中,并将该存档放到一个网站。现在用户可以下载该存档,解压缩它并拥有运行我的应用程序所需的一切。
我上面描述的过程似乎是向我分发应用程序二进制文件的一种相当常见的方式。但是,我无法弄清楚要使用哪些工具或如何配置它们以将我的应用程序构建为上述二进制发行版。
Cabal(图书馆)似乎具有为此所需的功能。通常Setup.hs
的脚本(没有 cabal(工具)或堆栈作为包装器)支持选项,例如--prefix
和--enable-relocatable
,允许您将包安装到给定的前缀并以确保在前缀 (作为一个整体)被移动到其他地方。
但是使用 rawSetup.hs
的缺点是它不能处理自动安装依赖项。而且由于许多大小适中的 Haskell 应用程序将具有数百个依赖项(或者至少我的依赖项),因此手动配置和构建它们中的每一个实际上并不可行。
安装依赖项问题的明显解决方案是使用包装工具,例如 cabal(该工具)或堆栈,因为它们专门用于处理大型依赖项树的问题。但是,它们似乎都有问题阻止我将我的应用程序构建为二进制发行版:
stack build
没有选项--prefix
or--enable-relocatable
而是总是安装到.stack-work
and~/.stack
。cabal v2-*
有选项--prefix
,--enable-relocatable
但似乎完全忽略它们,而是总是安装到dist-newstyle
and~/.cabal
。cabal v1-*
对于非常简单的情况,似乎可以做我想做的事。然而,对于更复杂的情况,它会产生模糊的构建失败,其中 GHC 抱怨没有从依赖项中找到模块,而 cabal 抱怨部分安装的包。但是,即使将这些故障放在一边,使用旧命令进行新的工作流程通常也不是一个好主意。
所以,既然我似乎对这些工具不走运,我还可以使用哪些其他工具将 Haskell 应用程序构建到二进制发行版中?或者也许我列出的工具之一实际上可以满足我的需求,而我只是以错误的方式使用它?
范围的一些限制:
- 目前我主要对 Windows 的构建感兴趣,但其他平台的解决方案也会很有趣。
- 当我谈论依赖时,我主要指的是 Haskell 依赖(即 Cabal 包)。捆绑外部 C 依赖项的解决方案会很有趣,但这不是严格的要求。