>Using Green Card

15. Using Green Card

So, you probably wonder, how can I actually make use of GreenCard and its output with the Haskell system you work with? This section outlines the series of steps you need to follow, concentrating for the moment on the use of GreenCard together with either Hugs or GHC.

15.1. Running Green Card

If you downloaded GreenCard as part of a binary distribution, you should have a binary that you can invoke like other command-line tools, i.e., assuming you have written the following spec:

module GCTest where

import StdDIS

%fun my_sin :: Double -> Double
%code res1=sin(arg1);

you can generate Hugs-compatible Haskell stubs as follows:

  green-card -c GCTest.gc -o GCTest.hs --target=hugs \
     -i/directory/where/you/put/StdDIS

and GHC-specific ones with

  green-card -c GCTest.gc -o GCTest.hs --target=ghc \
     -i/directory/where/you/put/StdDIS

In the case you're working on a Win32 platform and downloaded the GreenCard installer, the -i... option isn't required.

15.2. Compiling Green Card stubs

Having generated some Haskell stubs, and in the case of Hugs, some C code too, compiling these is the natural next step. If you're using GHC, the following should do:

 ghc -c GCTest.hs -o GCTest.o -fglasgow-exts 
     -i/directory/where/you/put/StdDIS

Upon completion, it should have produced the object file, GCTest.o, which can then be used and linked into your application.

The situation is a little bit different on the Hugs side. Here, you'll need to build a dynamically loadable extension module, which performs the calls to the external library you've written GreenCard stubs for. When Hugs loads in the Green Card generated Haskell stubs, it also looks for and hoist in the extension module at the same time.

The C code that goes into the extension module is naturally generated by Green Card, GCTest.c in our example. The details of how to compile this into an extension module differs between OSes; consult your Hugs documentation for exact guidelines (if any...). Here's how to compile it under an ELF-based OS (e.g., modern versions of Linux):

 gcc -fPIC -shared -o GCTest.so GCTest.c -I/usr/local/hugs/src

Notice that the command line needs to include the path to where you got your local copy of the GreenCard.h header file. It comes with both Hugs source and binary distributions (in the src subdirectory).

On the Win32 side, here's how to compile up the extension module using Visual C++,

  cl /nologo /LD /MD -o GCTest.dll GCTest.c -I/hugs/src

or, using the mingw32 backend of gcc that's supplied by the Cygwin toolchain distribution:

 gcc -mno-cygwin -o GCTest.o GCTest.c -I/hugs/src
 dllwrap -mno-cygwin --target=i386-mingw32 --export-all \
   --def HugsExt.def GCTest.o -o GCTest.dll

HugsExt.def is the module definition file, and contains the following

EXPORTS
initModule

Of course, if your stubs interface to some external library, you'll no doubt need to augment with at least extra -lwhatever options to satisfy the demands of the linker.