Haskell 通过 Nix 安装时未在 ghc-pkg 中列出的软件包
Haskell packages not listed in ghc-pkg when installed through Nix
我已经通过 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
我做错了什么?
您不能以这种方式在 Nix 中安装 Haskell 库,因为您使用的 ghc
编译器不会在您的用户配置文件中搜索库。因此,在那里安装库没有任何效果。 Nixpkgs user manual 中对此主题进行了非常详细的解释。我引用了“8.5.2.2。如何使用库安装编译器”中的相关内容:
GHC expects to find all installed libraries inside of its own lib directory. This approach works fine on traditional Unix systems, but it doesn’t work for Nix, because GHC’s store path is immutable once it’s built. We cannot install additional libraries into that location. As a consequence, our copies of GHC don’t know any packages except their own core libraries, like base, containers, Cabal, etc.
We can register additional libraries to GHC, however, using a special build function called ghcWithPackages. That function expects one argument: a function that maps from an attribute set of Haskell packages to a list of packages, which determines the libraries known to that particular version of GHC. For example, the Nix expression ghcWithPackages (pkgs: [pkgs.mtl]) generates a copy of GHC that has the mtl library registered in addition to its normal core packages:
$ 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
This function allows users to define their own development environment by means of an override. After adding the following snippet to ~/.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
]);
};
}
it’s possible to install that compiler with nix-env -f "<nixpkgs>" -iA myHaskellEnv.
我已经通过 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
我做错了什么?
您不能以这种方式在 Nix 中安装 Haskell 库,因为您使用的 ghc
编译器不会在您的用户配置文件中搜索库。因此,在那里安装库没有任何效果。 Nixpkgs user manual 中对此主题进行了非常详细的解释。我引用了“8.5.2.2。如何使用库安装编译器”中的相关内容:
GHC expects to find all installed libraries inside of its own lib directory. This approach works fine on traditional Unix systems, but it doesn’t work for Nix, because GHC’s store path is immutable once it’s built. We cannot install additional libraries into that location. As a consequence, our copies of GHC don’t know any packages except their own core libraries, like base, containers, Cabal, etc.
We can register additional libraries to GHC, however, using a special build function called ghcWithPackages. That function expects one argument: a function that maps from an attribute set of Haskell packages to a list of packages, which determines the libraries known to that particular version of GHC. For example, the Nix expression ghcWithPackages (pkgs: [pkgs.mtl]) generates a copy of GHC that has the mtl library registered in addition to its normal core packages:
$ 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
This function allows users to define their own development environment by means of an override. After adding the following snippet to ~/.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 ]); }; }
it’s possible to install that compiler with nix-env -f "<nixpkgs>" -iA myHaskellEnv.