据我了解,Nix是阴谋沙箱的替代品。我终于设法安装了Nix,但是我仍然不明白它如何代替沙箱。
我了解您不需要使用Nix和GHC的包装版本的阴谋;但是,如果要发布软件包,则有时需要使用cabal对其进行打包。因此,您需要能够在NIX中编写和测试电缆配置。你是怎样做的?
理想情况下,我想要一个类似于阴谋沙箱但在NIX中“包含”的环境,这可能吗?实际上,我真正想要的是等效的嵌套沙箱,因为我通常处理由多个程序包组成的项目。
目前,我从事2个或3个独立项目(P1,P2,P3),每个项目均由2个或3个阴谋模块/包装组成,对于P1,可以说是L11,L12(库)和E11(可执行文件)。E11取决于L12,后者取决于L11。我主要从库中拆分可执行文件,因为它们是私有的,并保存在私有的git repo中。
从理论上讲,每个项目都可以拥有自己的沙箱(在其子模块之间共享)。我试过了这一点(对于L11,L12和E11有一个公用的沙箱),但是它很快就很烦人,因为如果修改L11,则无法重建它,因为E11依赖它,所以我必须先卸载E11才能重新编译L11。可能并非完全如此,但是我遇到了类似的问题。如果我偶尔修改L11,那会很好,但实际上,我对它的更改程度超过了E11。
由于共享沙箱无法正常工作,因此我针对每种软件包解决方案都回到了一个沙箱。它正在工作,但不理想。主要问题是,如果我修改L11,则需要对其进行两次编译(一次在L11中,然后在E11中再次)。另外,众所周知,每次启动新的沙箱时,我都需要等待一段时间才能下载并重新编译所有软件包。
因此,通过使用Nix,我希望能够为每个项目设置单独的阴谋“环境”,从而解决了上述所有问题。
希望这更清楚。
这些天,我使用Nix和cabal进行所有开发,并且我可以高兴地说它们很好地协同工作。我当前的工作流程是非常新的,因为它依赖于nixpkgs
刚刚进入master分支的功能。这样,您需要做的第一件事就是nixpkgs
从Github克隆:
cd ~
git clone git://github.com/nixos/nixpkgs
(将来没有必要,但现在是必需的)。
现在我们有了一个nixpkgs
克隆,我们可以开始使用haskellng
包集了。haskellng
是对我们如何在Nix中打包内容的重写,并且对于我们更具可预测性(包名称与Hackage包名称匹配)和可配置性感兴趣。首先,我们将安装该cabal2nix
工具,该工具可以为我们自动化一些操作,并且还将安装cabal-install
以提供cabal
可执行文件:
nix-env -f ~/nixpkgs -i -A haskellngPackages.cabal2nix -A haskellngPackages.cabal-install
从这一点来看,一切都非常清晰。
如果您要开始一个新项目,则可以cabal init
像往常一样直接在一个新目录中调用。准备好构建时,可以将此.cabal
文件转换为开发环境:
cabal init
# answer the questions
cabal2nix --shell my-project.cabal > shell.nix
这将为您提供一个shell.nix
文件,可以与一起使用nix-shell
。不过,您并不需要经常使用它-通常,只有一次与一起使用cabal configure
:
nix-shell -I ~ --command 'cabal configure'
cabal configure
缓存所有内容的绝对路径,因此现在当您要构建时,只需cabal build
照常使用即可:
cabal build
每当.cabal
文件更改时,都需要重新生成shell.nix
-只需运行上面的命令,然后再运行即可cabal configure
。
该方法可以很好地扩展到多个项目,但是需要更多的手动工作才能将所有内容“粘合”在一起。为了演示它是如何工作的,请考虑我的socket-io
库。该库依赖engine-io
,我通常同时开发两者。
Nix化此项目的第一步是在default.nix
每个.cabal
文件旁边生成表达式:
cabal2nix engine-io/engine-io.cabal > engine-io/default.nix
cabal2nix socket-io/socket-io.cabal > socket-io/default.nix
这些default.nix
表达式是函数,所以我们现在不能做太多事情。为了调用这些函数,我们编写了自己的shell.nix
文件,该文件说明了如何组合所有内容。对于engine-io/shell.nix
,我们不必做任何特别聪明的事情:
with (import <nixpkgs> {}).pkgs;
(haskellngPackages.callPackage ./. {}).env
为此socket-io
,我们需要依靠engine-io
:
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
现在我们shell.nix
在每种环境中都可以使用,因此我们可以cabal configure
像以前一样使用。
此处的主要观察结果是,每当engine-io
更改时,我们都需要重新配置socket-io
以检测这些更改。这就像运行一样简单
cd socket-io; nix-shell -I ~ --command 'cabal configure'
Nix将注意到../engine-io
已更改,并在运行之前对其进行重建cabal configure
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句