2

我已经通过 Nix 安装了 GHC:

$ nix-env -i ghc

然后我安装了 aeson 包:

$ nix-env -f "<nixpkgs>" -iA haskellPackages.aeson

并将 GHC 指向 Nix 包文件夹:

$ export GHC_PACKAGE_PATH=~/.nix-profile/lib/ghc-8.0.1/package.conf.d/

这似乎有效:

$ ghc-pkg list
/Users/zoul/.nix-profile/lib/ghc-8.0.1/package.conf.d
    Cabal-1.24.0.0
    array-0.5.1.1
    …

但是上面的包列表中缺少aeson包,无法加载。尽管那里显然有一些东西:

$ ls /Users/zoul/.nix-profile/lib/ghc-8.0.1/ | grep ^ae
aeson-0.11.2.1

我究竟做错了什么?

4

1 回答 1

8

您不能以这种方式在 Nix 中安装 Haskell 库,因为ghc您使用的编译器不会在您的用户配置文件中搜索库。因此,在那里安装库没有任何效果。Nixpkgs 用户手册中详细解释了该主题。我引用了“8.5.2.2。如何使用库安装编译器”中的相关位:

GHC 期望在它自己的 lib 目录中找到所有已安装的库。这种方法在传统的 Unix 系统上运行良好,但不适用于 Nix,因为 GHC 的存储路径在构建后是不可变的。我们无法将其他库安装到该位置。因此,我们的 GHC 副本除了它们自己的核心库(如 base、container、Cabal 等)之外不知道任何包。

但是,我们可以使用名为 ghcWithPackages 的特殊构建函数向 GHC 注册其他库。该函数需要一个参数:一个从 Haskell 包的属性集映射到包列表的函数,它确定特定版本的 GHC 已知的库。例如,Nix 表达式 ghcWithPackages (pkgs: [pkgs.mtl]) 生成 GHC 的副本,该副本除了其正常的核心包之外还注册了 mtl 库:

$ nix-shell -p "haskellPackages.ghcWithPackages (pkgs: [pkgs.mtl])"

 [nix-shell:~]$ ghc-pkg list mtl
 /nix/store/zy79...-ghc-7.10.2/lib/ghc-7.10.2/package.conf.d:
     mtl-2.2.1

此功能允许用户通过覆盖来定义自己的开发环境。将以下代码段添加到 ~/.nixpkgs/config.nix 后,

{
  packageOverrides = super: let self = super.pkgs; in
  {
    myHaskellEnv = self.haskell.packages.ghc7102.ghcWithPackages
                     (haskellPackages: with haskellPackages; [
                       # libraries
                       arrows async cgi criterion
                       # tools
                       cabal-install haskintex
                     ]);
  };
}

可以使用 nix-env -f "<nixpkgs>" -iA myHaskellEnv 安装该编译器。

于 2017-01-19T14:31:07.960 回答