如何通过Cabal运行调用GHC API的程序A并配置正确包数据库?
解决Cabal运行调用GHC API程序时的依赖查找问题
当你的程序A(比如Shakefile)通过GHC API编译模块B时,stack run能正常工作但cabal run找不到依赖插件,核心原因是:Stack会自动将项目依赖的包数据库路径注入到运行环境,而Cabal默认不会把构建时的包数据库路径传递给运行的程序,导致GHC API无法定位到插件所在的包。
以下是几种可行的解决方法:
方法一:用cabal exec继承完整构建环境
这是最省心的方案,直接通过cabal exec启动程序,让它继承Cabal构建过程中的所有环境变量(包括GHC_PACKAGE_PATH),GHC API就能自动找到所有依赖包:
如果你的A是直接通过runhaskell运行的Shakefile:
cabal exec -- runhaskell Shakefile.hs
如果A是在.cabal文件中定义的可执行目标:
cabal exec -- A
方法二:手动为GHC API添加包数据库路径
在程序A的代码中,调用GHC API时手动指定Cabal本地包数据库的路径。这个路径通常位于项目根目录的dist-newstyle/packagedb/ghc-<你的GHC版本号>下:
import GHC import GHC.Paths (libdir) import DynFlags (gopt_set, Opt_KeepAllFiles, appendPackageFlags, PackageArg(..)) main = do -- 替换成你实际的GHC版本对应的包数据库路径 let localPkgDb = "dist-newstyle/packagedb/ghc-9.6.3" runGhc (Just libdir) $ do dflags <- getSessionDynFlags -- 将本地包数据库添加到GHC的搜索路径中 let newDflags = dflags `gopt_set` Opt_KeepAllFiles `appendPackageFlags` [PackageArg (PkgDbPath localPkgDb)] setSessionDynFlags newDflags -- 后续执行编译B模块的逻辑
方法三:在.cabal文件中配置环境变量
直接在可执行目标的配置里添加environment字段,将Cabal本地包数据库路径注入到GHC_PACKAGE_PATH中:
executable A main-is: Shakefile.hs build-depends: base, shake, ghc, clash-ghc, ghc-typelits-knownnat-solver -- 替换为你的GHC版本对应的包数据库路径 environment: GHC_PACKAGE_PATH = dist-newstyle/packagedb/ghc-9.6.3:$GHC_PACKAGE_PATH
配置完成后,直接用cabal run A即可正常运行。
内容的提问来源于stack exchange,提问作者Cactus
相关产品推荐
相关产品推荐

