GHC/As a library (up to 6.8)
Using GHC as a library
In GHC 6.5 and subsequently you can import GHC as a Haskell library, which lets you write a Haskell program that has access to all of GHC.
This page is a place for everyone to add
- Notes about how to get it working
- Comments about the API
- Suggestions for improvement
and so on.
You'll need to get a version of GHC that supports the GHC API. Either download ghc from CVS or use darcs: darcs get --partial http://darcs.haskell.org/ghc. There are also nightly snapshot distributions available.
To use the GHC API you say simply
Doing this imports the module GHC from the package ghc, which comes with GHC 6.5 and subsequent. The module GHC exports the "GHC API", which is still in a state of flux. Currently it's not even Haddock-documented. You can see the source code (which is somewhat documented) here http://darcs.haskell.org/ghc/compiler/main/GHC.hs
Here's an example main program that does it Media:Main.hs. (This version doesn't work anymore with the current GHC-6.6 API. This version does however. Can somebody upload this file to the wiki? Note: it actually fails to compile with error: Could not find module `Distribution.Compat.FilePath').
To compile Media:Main.hs, you have to turn on the flag "-package ghc", e.g.
ghc -package ghc Main.hs
Using the GHC library from inside GHCi
This works, to some extent. However, beware about loading object code, because there is only a single linker symbol table in the runtime, so GHCi will be sharing the symbol table with the new GHC session.
Prelude> :m GHC Prelude> :m +Module Prelude> :m +PackageConfig Prelude GHC> GHC.init (Just "/home/david/coding/haskell/ghc/usr/lib/ghc-6.5") Prelude GHC> session <- newSession Interactive Prelude GHC> setSessionDynFlags session =<< initPackages =<< getSessionDynFlags session Prelude GHC> setContext session  [mkModule (stringToPackageId "base") (mkModuleName "Prelude")] Prelude GHC> runStmt session "let add1 x = x + 1" Prelude GHC> runStmt session "add1 2" 3 Prelude GHC> :q Leaving GHCi.
Danger Will Robinson!! As of 15 October 2006, the GHC API has changed in ways that are not completely compatible with the documentation below!
GHC.init :: String -> IO ()
This should be called once only. Initializes with TopDir path (the String passed in)
First create a session:
GHC.newSession :: DynFlags.GhcMode -> Session
HscTypes.TargetId = TargetModule ModuleName | TargetFile FilePath (Maybe Phase)
The Phase determines which phase to start from (preprocessing)
Enter Expressions/Run Statements
GHC.runStmt :: Session -> String -> IO RunResult date GHC.RunResult = RunOk [Name] | RunFailed | RunException
runStmt session "let n = 2 + 2"The RunResult of this is RunOk [n] where n is bound to 4. So if we subsequently enter
runStmt session nthe RunResult is not updated but 4 will be printed
Get module dependency graph
GHC.getModuleGraph :: Session -> IO ModuleGraph
GHC.getBindings :: Session -> IO [TyThing]
Error messages can be routed through a callback mechanism.