我如何将 GHC 与不在当前工作目录中的 cabal 沙箱一起使用?

How can I use GHC with a cabal sandbox that's not in the current working directory?

如果我使用 cabal sandbox init 创建一个 cabal 沙箱,我可以使用 cabal replcabal exec ghc(i) 来处理这些包而无需创建项目:

$ mkdir /tmp/example && cd /tmp/example
$ cabal sandbox init
$ cabal install QuickCheck
$ cabal exec ghci
Prelude> :m Test.QuickCheck
Prelude Test.QuickCheck>

但是,如果我将路径更改为其他路径,即使更改为子目录,我也无法再访问这些包:

$ mkdir -p /tmp/example/sub && cd /tmp/example/sub
$ cabal exec ghci
Prelude> :m Test.QuickCheck
<no location info>:
    Could not find module ‘Test.QuickCheck’
    It is not a module in the current program, or in any known package.

有什么方法可以在不复制沙盒内容的情况下使用沙盒中的内容吗?

问题是 cabal 只会考虑当前工作目录中的沙箱。但是,您可以通过多个选项为 cabal 指定沙箱位置或为 GHC 指定包数据库。

使用 cabal 功能

您可以使用 cabal--sandbox-config-file 选项来指定沙箱配置,例如

$ cabal --sandbox-config-file=/tmp/example/cabal.sandbox.config exec ghci
Prelude> :m Test.QuickCheck
Prelude Test.QuickCheck>   

这也使您能够从其他地方更改沙箱,如果您只想将随机的东西安装到临时位置,这会派上用场:

$ cabal --sandbox-config-file=/tmp/example/cabal.sandbox.config install lens
$ cabal --sandbox-config-file=/tmp/example/cabal.sandbox.config repl
Prelude> :m Control.Lens
Prelude Control.Lens> :m Test.QuickCheck
Prelude Control.Lens Test.QuickCheck>

因为这会在一段时间后变得很麻烦,您可能应该添加一个别名

$ alias sandboxed-cabal="cabal --sandbox-config-file=/tmp/example/cabal.sandbox.config"
$ sandboxed-cabal repl
Prelude>

使用ghc -package-db

或者,您可以在使用 GHC 时直接指定包数据库 -package-db:

$ ghci -package-db /tmp/example/.cabal-sandbox/<ARCH>-packages.conf.d
Prelude> :m Test.QuickCheck
Prelude Test.QuickCheck>

<ARCH> 取决于您的系统和使用的 GHC,例如在 64 位 Linux 和 GHC 7.10.3 上它是 x86_64-linux-ghc-7.10.3-packages.conf.d。然后您可以使用该数据库中的所有包:

$ ghci -package-db /tmp/example/.cabal-sandbox/<ARCH>-packages.conf.d
Prelude> :m Control.Lens
Prelude Control.Lens> 

同样,别名应该派上用场。

使用GHC_PACKAGE_PATH

最后但同样重要的是,您可以调整环境变量。但是,如果环境变量 GHC_PACKAGE_PATH 存在,它将覆盖 GHC 的常用包数据库,因此您要么需要检查 ghc-pkg list 并添加它们

$ GHC_PACKAGE_PATH=/opt/ghc/7.10.3/lib/ghc-7.10.3/package.conf.d/:/tmp/example/.cabal-sandbox/x86_64-linux-ghc-7.10.3-packages.conf.d ghci

或使用 -global-package-db and -user-package-db 重新启用它们:

$ GHC_PACKAGE_PATH=/tmp/example/.cabal-sandbox/x86_64-linux-ghc-7.10.3-packages.conf.d ghci -global-package-db -user-package-db