如何使用Haskell Stack创建一个Nix包

3
我需要从一个带有Postgres模板的项目堆栈创建Nix包。
基本上是这样的:我有一个安装了NixOS的虚拟机,我需要将我的项目移植到另一个安装了NixOS的虚拟机。为此,我将使用nix copy命令,但在此之前,我需要以某种方式“安装”我的项目,使其位于/nix/store目录中。
我尝试通过查看另一个发布的问题“从stack项目生成Nix包”来做同样的事情。
来吧。我所做的是:
cd /home/ProjetoApp
stack new TesteYesod yesod-postgres
cd TestYesod
stack init --resolver lts-11.22
stack install yesod-bin --install-ghc

我在 stack.yaml 文件中添加了:

nix
pure: true
enable: true
packages: [postgresql]

目前为止一切顺利。我只能编译和执行堆栈。然后我尝试生成一个nix包。在stack.yaml中,我做了以下操作:

nix
pure: true
enable: true
shell-file: default.nix

在 default.nix 文件中,我做了以下操作:

{nixpkgs ? import <nixpkgs> { }, ghc ? nixpkgs.ghc}:

with nixpkgs;

haskell.lib.buildStackProject {
   name ="teste-yesod-1.0.0";
   src = ./.;
   buildInputs = [ postgresql ];
   inherit ghc;
}

如果我这样做:

nix build

发生时间:

builder for '/nix/store/rckhmkgrkb6nzn7dkqqldfdm8cilpya2-teste-yesod 
1.0.0.drv' failed with exit code 1; last 5 log lines:
unpacking sources
unpacking source archive /nix/store/ 
n62hzn4igi1b7khksa6sp3cq8gk4h344-TesteYesod
source root is TestYesod
patching sources
configuring
[0 built (1 failed), 0.0 MiB DL]
error: build of '/nix/store/rckhmkgrkb6nzn7dkqqldfdm8cilpya2-teste-yesod- 
1.0.0.drv' failed

如果源码分布在多个目录中,如何指示nix?

看起来和我这里的问题很相似:https://unix.stackexchange.com/questions/498435/how-do-i-diagnose-a-failing-nix-build/498695#498695 - Chris Stryczynski
尝试使用 nix-build --debug - Chris Stryczynski
1个回答

1
如果你想要快速解决问题,以下方法应该有效:
{ nixpkgs ? import (builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/d42ef371c9b1b532400b0f2820885e575f4f1617.tar.gz";
    sha256 = "0irb4zb6hdgaah238244jk2xf63xfb20xy3plb1194pd4xbgdr3r";
  }) {}
, ghc ? nixpkgs.ghc
}:

with nixpkgs;

haskell.lib.buildStackProject {
   name ="TesteYesod";
   src = ./.;
   buildInputs = [ postgresql ];
   inherit ghc;
}

在当前的18.09版本中,buildStackProject存在问题。由于preConfigure脚本微妙地失败,导致错误信息不存在,并包含以下内容:
    addStackArgsHook = ''
for pkg in ''${pkgsHostHost[@]} ''${pkgsHostBuild[@]} ''${pkgsHostTarget[@]}
do
  [ -d "$pkg/lib" ] && \
    export STACK_IN_NIX_EXTRA_ARGS+=" --extra-lib-dirs=$pkg/lib"
  [ -d "$pkg/include" ] && \
    export STACK_IN_NIX_EXTRA_ARGS+=" --extra-include-dirs=$pkg/include"
done
    '';

在您的情况下,stack 是循环中最后一个被处理的依赖项(也许在所有18.09的buildStackProject调用中都是如此,我不确定),但它不包含任何/lib/include目录,因此preConfigure脚本退出时的退出代码为1,因此整个构建过程停止。这只是因为使用了简写形式的&&,如果有一个适当的if,它就可以工作。
然而,在master中已经修复了这个问题(https://github.com/NixOS/nixpkgs/pull/53618),因此只需使用更新的nixpkgs即可解决该问题。无论如何,如果想要充分利用Nix的可复制性保证,固定nixpkgs是必须要做的,因为您无法知道是否使用了相同的nixpkgs提交,因此可能会使用不同版本的系统软件包。
(如果您想知道我是如何调试的 - 似乎问题出在preConfigure步骤中,所以我查看了generic-stack-builder.nix中的代码,发现preConfigure可被覆盖,将其从那里复制到default.nix中,并在顶部添加了set -x。这向我展示了上面的问题,并促使我去查看主文件是否有更改自18.09以来。另一个解决方法可能只是在preConfigure脚本中添加true,如果它还没有在master中修复,但这并不是必要的。)
(另外,我已经打开https://github.com/NixOS/nixpkgs/issues/55548以将修复程序回溯到18.09。))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接