如何解决cabal-3与GHC(含ghc-pkg)的包识别兼容问题?
你遇到的这个问题是Cabal 3.x引入的**用户专属包存储(per-user package store)**和GHC传统包注册机制不兼容的典型情况——cabal install --lib安装的包默认存放在GHC/ghc-pkg未自动识别的独立路径里,导致工具找不到依赖。下面给几个比手动修改GHC_PACKAGE_PATH更优雅的解决方案:
方案1:用Cabal自带命令替代直接调用GHC/GHCi(最省心)
Cabal的v2系列命令(现在已是默认行为)会自动处理依赖路径,完全不用手动配置环境变量:
- 要运行你的
t1.hs文件,直接执行:cabal run -- t1.hs - 要进入GHCi调试带依赖的代码,执行:
cabal repl --build-depends safe
如果是同一个项目里经常用到某些依赖,还可以在项目根目录创建一个cabal.project文件,把依赖写进去:
packages: . extra-deps: safe
之后直接敲cabal repl,Cabal会自动加载所有配置好的依赖,不用每次都指定--build-depends。
方案2:用ghcup管理Haskell环境(推荐Windows用户)
Chocolatey安装的Haskell环境在工具链同步上不够灵活,而官方推荐的ghcup是专门的Haskell工具链管理器,它会自动处理Cabal和GHC的路径兼容问题:
- 安装ghcup后,重新通过它安装GHC和Cabal
- ghcup会自动配置好包存储路径的关联,后续更新工具链时也会同步调整,完全不用你手动修改系统变量。
方案3:安装包时指定注册到用户包数据库
如果还是习惯直接调用GHC/GHCi,可以在安装包时指定把包注册到GHC默认识别的用户包数据库,而不是默认的store路径:
cabal install safe --lib --package-db=user
这样安装的包会被放到GHC自动扫描的用户包DB(路径一般是%APPDATA%\ghc\ghc-8.10.2\package.db),GHC和GHCi就能直接找到依赖。唯一需要注意的是,不同GHC版本的用户包DB是分开的,换版本时需要重新安装对应依赖,但比手动改环境变量省心很多。
方案4:切换到Stack包管理器
Stack是另一个流行的Haskell包管理器,它默认使用隔离的快照环境,会自动处理所有包的路径和注册问题,完全不会出现GHC找不到包的情况:
- 安装Stack后,执行
stack install safe安装依赖 - 之后直接用
stack ghci t1.hs就能运行代码,不用任何额外配置。
内容的提问来源于stack exchange,提问作者Vladimir

