2017-12-27 144 views
1

我有一个本地创作Haskell的项目,这既产生:如何使用堆栈来安装本地创作的Haskell模块以实现全局使用?

  1. 二进制可执行文件,
  2. 几个新的哈斯克尔模块,我想发到我的其他访问,哈斯克尔基础,可执行文件。

后:

stack build 
stack install 

我发现:

  1. 二进制可执行文件(#1,以上)运行在任何目录下就好了。
  2. 但是,新的Haskell模块(上面#2)只有在我从我的项目目录中运行时才能找到! (也就是说,对于除#1以外的任何可执行文件)。

我需要能够从任何地方找到新模块。 我该如何做到这一点?

+0

听起来和[这个问题只有几个小时前]类似(https://stackoverflow.com/questions/47989939/is-there-a-declarative-way-to-specify-packages-to-be-installed- into-global-proje),在那里我建议你使用Cabal-install而不是stack,那么你永远不需要担心模块安装是全局的。 – leftaroundabout

+0

感谢您的评论。是的,“cabal install”确实解决了我的问题。然而,现在我已经有了两个单独的,并行的,大部分冗余的Haskell设备来啃硬盘空间,这看起来非常浪费和不必要。这尤其令人愤慨,因为我生产的二进制可执行文件可以在任何目录下运行,这意味着它知道如何从我的系统的任何地方(因为它导入它们)找到我的新Haskell模块。那么,为什么我不能让这些新模块可用于其他Haskell可执行文件呢? – dbanas

+0

这绝对是不必要的,这就是为什么我在我的笔记本电脑上只使用_only_ Cabal-install,而仅使用Travis的Stack。 - 请注意,您的可执行文件找到导入模块的方式与编译器为源文件找到它们的方式有很大不同。事实上,如果你静态链接,那么就不需要找到任何外部的东西,因为一切都已经包含在二进制文件中了。如果您动态链接,它会查找特定散列动态库文件的硬编码路径,但这只适用于版本解析程序和链接程序在完成之前完成其工作。 – leftaroundabout

回答

1

每个堆栈项目位于其自己的沙箱中,因此编译的模块只能在该项目中使用。编译的依赖项(来自堆栈快照)有时会在项目之间共享。

请注意,您可以在软件包列表中列出相对路径,并指向该软件包。它会重新构建,但可以通过这种方式直接在另一个项目中使用。为什么多余的建筑? Stack与Cabal-install有不同的项目模型 - 它不允许包DB的变化影响其他项目的构建。

共享这样一个包的一个选择是让它在git仓库中使用https://docs.haskellstack.org/en/stable/custom_snapshot/,但这些东西还是有点新的。

+0

感谢您的回应。所以,如果我理解你在说什么,那听起来像为Haskell可执行文件构建的模块,使用动态插件的自定义风格,并不适合用堆栈构建/安装。相反,它们应该用cabal制造/安装。这是一个公平的总结吗? – dbanas

+0

哦,我没有意识到你正在尝试动态加载模块。如果您在项目中执行“堆栈生成pkg-x”,那么这些模块将在由'stack exec'设置的GHC_PACKAGE_PATH指定的包DB中可用。这听起来像你想要更多的全球共享,但考虑到动态插件的工作,依赖版本需要排队,所以它应该在一个堆栈项目内完成...... 不,你可能不应该使用cabal for这个。很确定新构建的东西实际上会让这个更笨拙,因为你需要指定一个特定的软件包编号 – mgsloan

+0

谢谢!我想确保我明白了:所以,我真正需要做的是在将新的自定义插件添加到其堆栈项目描述之后,重新生成此“外部”可执行文件。是对的吗?换句话说,尝试构建可执行文件,使用一个堆栈项目和插件,使用不同的堆栈项目,这是一种固有的缺陷。如果这是正确的,那么潜在的插件开发人员似乎非常脆弱和限制。我认为这是一个设计良好的/有记录的API(可执行文件)旨在防止的。我必须在这里错过一些基本的东西。 – dbanas