The 'linkcore' program transforms a single Haskell module to a single, closed
External Core module.
Previous versions used the GHC API to automatically trace dependencies and
build External Core on demand for any intra-package dependencies of
the given Haskell module. This was overly complicated (requiring
multiple coexisting builds of GHC) and in version 0.4, I eliminated
the dependency on the GHC API.
As of version 0.4, this program is a very simple wrapper around the
Dependencies and Merge modules of the External Core library. It
executes a GHC command, which you can provide as a configure option
and which defaults to "ghc", to regenerate Core code if
necessary. (Note that as of version 6.10.4, GHC's recompilation
checker won't generate .hcr files if the source is older than the .o
and .hi files but the .hcr files don't exist. On the other hand,
you can pass the --ghc-flag=-fforce-recomp option to linkcore to
force GHC to recompile unconditionally.)
===== Prerequisites ====
For the Core Linker to be useful, you will at least need to have built External
Core for all the GHC libraries. For more details, see the HOWTO file
in this package (henceforth "HOWTO").
You also need to install the extcore package from:
(or using cabal-install).
The extcore package includes a patch for the GHC libraries (see the README file
in the extcore package.)
There are two ways to proceed:
(1) Build GHC from source, applying the patches described in HOWTO.
(2) Use a plain old installed version of GHC.
Option (1) will allow you to run the stand-alone External Core interpreter on some
very simple examples, and will illustrate how you can add an appropriate set of
primops so that you can implement your own External Core back-end.
Option (2) will probably not allow you to execute any Core code, but will still
allow running the Core linker so you can see what it does.
The instructions that follow assume you've done (1).
===== Building =====
Suppose your GHC build tree that contains External Core for the GHC libraries lives under:
Then you do:
runhaskell configure --configure-option=--with-ghc=$TOP/ghc
At this stage you can specify zero or more command-line flags to be
passed to GHC (when generating Core). After running the configure
command, you can look at Config.hs to see the list of flags that was
generated. You can also pass extra GHC flags to linkcore itself on the
For example, the command line I would use to configure linkcore is:
runhaskell Setup configure --configure-option=--with-ghc=$TOP/ghc/ghc/stage1-inplace/ghc \
--configure-option=--ghc-flag=-O2 --configure-option=--ghc-flag=-DSLOW \
After that, you do:
runhaskell Setup build
runhaskell Setup install
like usual. This installs an executable called "linkcore", wherever your Cabal installs executables.
====== Running =====
$ cat > hello.hs
module Main where
main = putStrLn "hello world!"
$ linkcore --package-root=$TOP/ghc/libraries --package-root=$TOP/ghc/libraries/base/dist/build --package-root=$TOP/ghc/libraries/integer-gmp \
hello.hs -o hello_out.hcr
What are all these flags doing? They're telling the Core linker to look for External Core source code in the library
trees you compiled to External Core in an earlier step. Also, the -o flag tells the linker to put the Core output in hello.hcr.
If I want to add another GHC flag, I could say, for example:
$ linkcore --ghc-flag=-O0 --package-root=$TOP/ghc/libraries --package-root=$TOP/ghc/libraries/base/dist/build \
--package-root=$TOP/ghc/libraries/integer-gmp hello.hs -o hello_out.hcr
This step may be slow. On my machine, reading in all the GHC library files (even just the 61 imported implicitly
by the "hello world" program) takes several seconds.
Now you can look at the output file hello_out.hcr, manipulate it with the External Core library, etc.
====== More detailed instructions ======
See the HOWTO file in this distribution.
====== Bugs ======
Almost certainly. Please direct bug reports or questions to:
Tim Chevalier <firstname.lastname@example.org>