Haskell 如何让阴谋集团和尼克斯合作

Haskell 如何让阴谋集团和尼克斯合作,haskell,cabal,nix,Haskell,Cabal,Nix,据我所知,Nix是阴谋集团沙箱的替代品。 我终于设法安装了Nix,但我仍然不明白它如何能取代沙箱 我知道你不需要阴谋集团使用Nix和GHC的包装版本;但是如果你想 要发布一个包,您需要在某个时候使用cabal对其进行打包。因此,您需要能够在NIX中编写和测试您的阴谋集团配置。你是怎么做到的 理想情况下,我想要一个类似于阴谋集团沙箱但“包含”在NIX中的环境,这可能吗?事实上,我真正想要的是嵌套沙盒的等价物——因为我通常处理由多个包组成的项目 更新我当前的工作流程 目前,我从事2或3个独立项目(P

据我所知,Nix是阴谋集团沙箱的替代品。 我终于设法安装了Nix,但我仍然不明白它如何能取代沙箱

我知道你不需要阴谋集团使用Nix和GHC的包装版本;但是如果你想 要发布一个包,您需要在某个时候使用cabal对其进行打包。因此,您需要能够在NIX中编写和测试您的阴谋集团配置。你是怎么做到的

理想情况下,我想要一个类似于阴谋集团沙箱但“包含”在NIX中的环境,这可能吗?事实上,我真正想要的是嵌套沙盒的等价物——因为我通常处理由多个包组成的项目

更新我当前的工作流程 目前,我从事2或3个独立项目(P1、P2、P3),每个项目由2或3个阴谋集团模块/包组成,比如P1:L11、L12(库) 和E11(可执行文件)。E11依赖于L12,而L12依赖于L11。我主要从库中分离可执行文件,因为它们是私有的,保存在私有的git repo上

理论上,每个项目都可以有自己的沙箱(在其子模块之间共享)。我尝试过(为L11、L12和E11提供了一个公共沙盒),但这很快就会让人恼火,因为如果修改L11,就无法重建它,因为E11依赖于它,所以我必须先卸载E11才能重新编译L11。 可能情况并非如此,但我遇到了类似的问题。 如果我偶尔修改L11,这会很好,但实际上,我对它的修改比E11更多

由于共享沙箱不起作用,所以我回到了针对每个包解决方案的一个沙箱。它工作正常,但不太理想。 主要问题是,如果修改L11,我需要编译它两次(一次在L11中,然后在E11中再次编译)。而且,正如大家所知,每次我启动一个新的沙盒时,我都需要等待一段时间才能下载并重新编译包中的所有内容

因此,通过使用Nix,我希望能够为每个项目建立单独的阴谋集团“环境”,从而解决上述所有问题


希望这更清楚。

这些天来,我使用尼克斯和卡巴尔进行了所有的开发,我可以高兴地说,他们非常和谐地工作。我当前的工作流非常新,因为它依赖于刚刚到达主分支的
nixpkgs
中的功能。因此,您需要做的第一件事是从Github克隆
nixpkgs

cd~
git克隆git://github.com/nixos/nixpkgs
(在未来这是不必要的,但现在是)

单个项目的使用 现在我们有了一个
nixpkgs
克隆,我们可以开始使用
haskellng
包集了
haskellng
是对我们如何在Nix中打包东西的重写,我们感兴趣的是它更可预测(包名与黑客包名匹配)和更可配置。首先,我们将安装
cabal2nix
工具,它可以为我们自动化一些事情,我们还将安装
cabalinstall
以提供
cabal
可执行文件:

nix env-f~/nixpkgs-i-A haskellngPackages.cabal2nix-A haskellngPackages.cabal-install
从这一点来看,一切都很顺利

如果你正在启动一个新项目,你可以像平常一样,在一个新目录中调用
cabalinit
。当您准备好构建时,可以将此
.cabal
文件转换为开发环境:

cabalinit
#回答问题
cabal2nix——shell my-project.cabal>shell.nix
这将为您提供一个
shell.nix
文件,该文件可与
nixshell
一起使用。不过,您不需要经常使用它-您通常只会在
cabal configure
中使用它:

nix shell-I~--命令“阴谋集团配置”
cabal configure
缓存所有内容的绝对路径,因此现在,当您想要构建时,只需正常使用
cabal build

cabalbuild
每当
.cabal
文件发生更改时,您都需要重新生成
shell.nix
——只需运行上面的命令,然后再运行
cabal configure

多项目使用 这种方法可以很好地扩展到多个项目,但需要更多的手工工作才能将所有内容“粘合”在一起。为了演示这是如何工作的,让我们考虑一下我的库。这个库依赖于,我通常同时开发这两个库

禁用此项目的第一步是沿每个单独的
文件生成
default.Nix
表达式。cabal
文件:

cabal2nix引擎io/engine-io.cabal>engine io/default.nix
cabal2nix套接字io/socket-io.cabal>socket io/default.nix
这些
default.nix
表达式是函数,所以我们现在不能做太多。为了调用函数,我们编写了自己的
shell.nix
文件,解释如何组合所有函数。对于
引擎io/shell.nix
,我们不需要做任何特别聪明的事情:

with (import <nixpkgs> {}).pkgs;
(haskellngPackages.callPackage ./. {}).env
现在我们在每个环境中都有了
shell.nix
,所以我们可以像以前一样使用
cabalconfigure

这里的关键观察是,每当
引擎io
发生变化时,我们需要重新配置
套接字io
,以检测这些变化。这就像跑步一样简单

cd插座io;nix shell-I~--命令“阴谋集团配置”

Nix会注意到
。/engine io
已更改,并在运行
cabal configure

之前重新构建它。这可能会有所帮助:我已经阅读了很多次,但无法提取所需的信息。谢谢!这看起来比我现在做的要简单得多。你能详细介绍一下haskellng正在做什么(“我们如何在nix中打包东西”)?跨项目依赖关系的工作流是否与您在中描述的类似,或者是否已发生更改?@KrisNuttycombe
with (import <nixpkgs> {}).pkgs;
let modifiedHaskellPackages = haskellngPackages.override {
      overrides = self: super: {
        engine-io = self.callPackage ../engine-io {};
        socket-io = self.callPackage ./. {};
      };
    };
in modifiedHaskellPackages.socket-io.env