如何使用Haskell堆栈创建Nix包

时间:2019-01-28 21:40:11

标签: haskell stack yesod nix

我需要使用postgres模板从项目堆栈中创建nix包。

基本上是以下内容:我有一台带有NixOS的虚拟机,我需要将我的项目移植到另一个带有NixOS的项目。为此,我将使用nix copy命令,但在需要以某种方式“安装”我的项目使其位于/ nix / store中之前。

我尝试着同样的方法看发布在“从堆栈项目生成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源分布在多个目录中?

1 个答案:

答案 0 :(得分:0)

如果您想快速修复,以下方法应该起作用:

{ 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调用中),但其中不包含{{1 }}或/lib目录,因此/include脚本所退出的退出代码为preConfigure,因此整个构建过程都退出了。这仅仅是因为速记1,如果有适当的&&,它会起作用。

然而,它已经在if中得到了修复(https://github.com/NixOS/nixpkgs/pull/53618),因此只需使用较新的nixpkgs即可解决该问题。如果您想最大程度地使用Nix的可复制性保证,则无论如何都要固定nixpkgs,因为您可能不知道自己使用的是同一个nixpkgs commit,因此您可能会使用不同版本的系统软件包。

((如果您想知道我是如何调试的-看来问题出在master步骤中,所以我看了preConfigure中的代码,发现generic-stack-builder.nix是可重写的,将代码从那里复制粘贴到preConfigure并在顶部添加一个default.nix。这向我展示了上面的问题,并提示我去查看master中的文件以查看是否存在自18.09开始没有变化。另一个解决方法是,如果set -x中尚未修复true脚本,但只需将preConfigure添加到master脚本中。)

(此外,我已经打开https://github.com/NixOS/nixpkgs/issues/55548将该修补程序反向移植到18.09。)