[Haskell-cafe] Integrate GHC-API with Cabal

Daniel Gröber dxld at darkboxed.org
Wed Jul 25 21:38:28 UTC 2018


On Wed, Jul 25, 2018 at 10:33:45AM +0200, Félix Baylac wrote:
> Before generating this database, I need to retrieve the exported symbol of a 
> package. So far, I have been gathering the dependencies and integrating them in
> the GHC pkg database using an external stack call, I then parse the cabal file
>  and load the exposed modules using the GHC API and gather the exported
>  symbols*.
> It works pretty reliably on the simple packages, however, I end up with some 
> missing dynamic flags for some more advanced packages (missing c includes, c 
> libraries, ASM flags, etc.). I then started to parse and load these missing 
> attributes to GHC until I stepped back for a moment and realized I was 
> re-implementing cabal build.

I think you might be interrested in one of my packages,
[cabal-helper](https://hackage.haskell.org/package/cabal-helper). It's
geard more towards editor tooling but I think it should work for your
use case too.

Basically you'd have to do `cabal install --only-dependencies && cabal
configure && cabal build` for each package you want to inspect and
then cabal-helpers API boils down to giving you a list of GHC
flags/module names you need to pass into the GHC API to make it work.

(The `cabal build` step is needed to run preprocessors like hsc2hs and
compile C dependencies, but once cabal has taken care of that you can
usually just load the package without problems.)

Here's some example code you can use to get started (from our tests):

Quoting from the above, the main part is:

let qe = mkQueryEnv dir (dir </> "dist")
cs <- runQuery qe $ components $ (,,) <$> entrypoints <.> ghcOptions
forM cs $ \(ep, opts, cn) -> do

where `dir` is the directory containing the cabal file of the project
you're trying to load into GHC. The do block gets called for each
component in the cabal project with 1) `ep` a datatype containing
(among other things) the list of modules you need to pass to GHC, 2)
the GHC flags `opts` and 3) `ch` the component name.

API docs are over here:
They're probably not all that much use if you're not familliar with
Cabal's inner workings though so feel free to ask me questions.


More information about the Haskell-Cafe mailing list