By default, GHC under Windows will link in a static copy of the GMP library. (The base libraries/RTS using it in the implementation of Integers.) This may not be desirable for licensing reasons (GMP being LGPL-licensed) for some deployments/uses of Haskell applications, as it requires you to supply (at least) the object code for your application along with the executable.
One way to achieve freedom from this constraint (should you view it as such :-) ), is to instead dynamically link in GMP by placing it in a DLL. Here are the instructions for how to do this [nothing too magic or new here, but haven't seen this spelled out in writing before..]: - Build a version of the GMP library as a DLL, or pick up a binary bundle (see attachment.)
- Download a recent mingw snapshot of GNU binutils, containing a more recent version of GNU ld than the one that GHC bundles in its binary distributions for Windows. GHC bundles 2.17, GNU binutils 2.19 is what you are (at least) after. The mingw download page has links to a 2.19 snapshot.
- If you prefer not to do this and/or doesn't have a mingw development environment set up already, you may instead choose to side-effect the GHC binary installation tree instead. See below for steps required.
- Install the GNU binutils snapshot, either on top of your mingw tree or separate, but adjusting your PATH to fit. i.e., from within a shell, "ld --version" needs to report the version of this snapshot.
- For the Haskell application you want to link against the GMP DLL, create a gmp directory at the top of its tree -- if your application lives in c:\projects\haskell\app, create c:\projects\haskell\app\gmp Unpack the contents from the first step into this directory (If you built from sources, that would be the contents of the .libs/ directory.)
- Change your Makefile / ghc command-line / .cabal file , adding -Lgmp (to ghc-options: for .cabal, for instance.)
- Re-link your application. That should give you a binary which is now dependent on a GMP DLL to operate. If you try invoking it, the Windows loader will complain about a missing libgmp-3.dll a binary whi.
- To have the DLL be correctly resolved, either bring the gmp directory into your PATH, copy the GMP DLL into a shared DLL directory or copy it into the same directory as the binary.
- When distributing your application, include the DLL along with its licensing terms (the attached bundle contains this.)
- That's it! If you want to switch back to doing the default thing of statically linking GMP, simply drop the use of -Lgmp in your builds.
Changes required to work with GHC's (<= 6.10.1, at least) bundled version of ld:
- Locate the top of your GHC installation tree -- c:\ghc\ghc-6.10.1\ perhaps?
- Rename/move libgmp.a to libgmp-static.a in that directory
- From the GMP DLL binary bundle (see attached), copy in the libgmp.dll.a into that same directory.
- Rename libgmp.dll.a as libgmp.a
- Re-link your application with GHC (i.e., no Makefile / .cabal changes required.)
- This should give you a binary like in the above set of steps; please follow the instructions/advice on how to proceed from there.
- You may very well want to switch back to the default, static link, story while developing internally. To do this, simply rename libgmp.a to libgmp-dyn.a and libgmp-static.a to libgmp.a to revert back to normal.
That completes the story; it's length and the number of steps may make it look complex, but it's really a quite straightforward process. Hope it is of some use -- if you found it useful or have suggestions for improvement, please let me know.
Sigbjorn Finne -- sigbjorn.finne at gmail.com
|
 Updating...
Sigbjorn Finne, Jan 7, 2009, 3:32 PM
|