[project @ 1999-05-04 08:30:44 by sof]
authorsof <unknown>
Tue, 4 May 1999 08:30:44 +0000 (08:30 +0000)
committersof <unknown>
Tue, 4 May 1999 08:30:44 +0000 (08:30 +0000)
a howto on Win32 DLLs

ghc/docs/users_guide/win32-dlls.sgml [new file with mode: 0644]

diff --git a/ghc/docs/users_guide/win32-dlls.sgml b/ghc/docs/users_guide/win32-dlls.sgml
new file mode 100644 (file)
index 0000000..8c3090b
--- /dev/null
@@ -0,0 +1,169 @@
+%************************************************************************
+%*                                                                      *
+<sect>Building and using Win32 DLLs
+<label id="win32-dlls">
+<p>
+<nidx>Dynamic link libraries, Win32</nidx>
+<nidx>DLLs, Win32</nidx>
+%*                                                                      *
+%************************************************************************
+
+On Win32 platforms, the compiler is capable of both producing and using
+dynamic link libraries (DLLs) containing ghc-compiled code. This
+section shows you how to make use of this facility.
+
+%************************************************************************
+%*                                                                      *
+<sect1>Linking with DLLs
+<label id="win32-dlls:link">
+<p>
+%*                                                                      *
+%************************************************************************
+
+The default on Win32 platforms is to link applications in such a way
+that the executables will use the Prelude and system libraries DLLs,
+rather than contain (large chunks of) them. This is transparent at the
+command-line, so 
+
+<tscreen><verb>
+sh$ cat main.hs
+module Main where
+main = putStrLn "hello, world!"
+sh$ ghc -o main main.hs
+ghc: module version changed to 1; reason: no old .hi file
+sh$ strip main.exe
+sh$ ls -l main.exe
+-rwxr-xr-x   1 544      everyone     6144 May  3 17:11 main.exe*
+sh$ ./main
+hello, world!
+sh$ 
+</verb></tscreen>
+
+will give you a binary as before, but the <tt>main.exe</tt> generated
+will use the Prelude and RTS DLLs instead.
+
+6K for a <tt>"hello, world"</tt> application - not bad, huh? :-)
+
+%************************************************************************
+%*                                                                      *
+<sect1>Not linking with DLLs
+<label id="win32-dlls:linking-static">
+<nidx>-static option (Win32)</nidx>
+<p>
+%*                                                                      *
+%************************************************************************
+
+If you want to build an executable that doesn't depend on any
+ghc-compiled DLLs, use the <tt>-static</tt> option to link in
+the code statically.
+
+Notice that you cannot mix code that has been compiled with
+<tt>-static</tt> and not, so you have to use the <tt>-static</tt>
+option on all the Haskell modules that make up your application.
+
+%************************************************************************
+%*                                                                      *
+<sect1>Creating a DLL
+<label id="win32-dlls:create">
+<p>
+<nidx>Creating a Win32 DLL</nidx>
+<nidx>--mk-dll</nidx>
+%*                                                                      *
+%************************************************************************
+
+Sealing up your Haskell library inside a DLL is quite straightforward;
+compile up the object files that make up the library, and then build
+the DLL by issuing the following command:
+
+<tscreen><verb>
+sh$ ghc --mk-dll -o HSsuper.dll A.o Super.o B.o libmine.a -lgdi32
+</verb></tscreen>
+
+By feeding the ghc compiler driver the option <tt>--mk-dll</tt>, it
+will build a DLL rather than produce an executable. The DLL will
+consist of all the object files and archives given on the command
+line.
+
+A couple of things to notice:
+
+<itemize>
+<item>
+When compiling the module <tt>A</tt>, the code emitted by the compiler
+differs depending on whether or not the functions and data it is
+importing from other Haskell modules correspond to symbols that are
+packaged up in a ghc-compiled DLL. To resolve whether such imports are
+'DLL imports' or not, the following rules are used:
+
+<itemize>
+<item>
+If the compiler imports from a module that's in the same directory as
+the one being compiled, it is assumed to not belong to a different DLL
+(or executable) than the module being processed, so none of the
+same-directory imports are considered 'DLL imports'.
+
+<item>
+If a directory contains the (probably empty) file
+<tt>dLL_ifs.hi</tt>, the code corresponding to the interface
+files found in that directory are assumed to live in a DLL
+separate from the one being compiled. 
+
+Notice that the first rule takes precedence over this one, so if
+you're compiling a module that imports from a Haskell module whose
+interface file live in the same directory, <em>and</em> that directory
+also contains the file <tt>dLL_ifs.hi</tt>, the import is still not
+being considered to be a 'DLL import'.
+
+<item>
+If compiling with the option <tt>-static</tt>, the previous rule
+is disabled.
+</itemize>
+
+So, in short, after having built your Haskell DLL, make sure you
+create the file <tt>dLL_ifs.hi</tt> in the directory that contains
+its interface files. If you don't, Haskell code that calls upon entry
+points in that DLL, will do so incorrectly, and a crash will result.
+(it is unfortunate that this isn't currently caught at compile-time).
+
+<item>
+By default, the entry points of all the object files will
+be exported from the DLL when using <tt>--mk-dll</tt>. Should you want
+to constrain this, you can specify the <em>module definition file</em>
+to use on the command line as follows:
+
+<tscreen><verb>
+sh$ ghc --mk-dll -o .... -optdll--def -optdllMyDef.def
+</verb></tscreen>
+
+See Microsoft documentation for details, but a module definition file
+simply lists what entry points you want to export. Here's one that's
+suitable when building a Haskell COM server DLL:
+
+<tscreen><verb>
+EXPORTS
+ DllCanUnloadNow     = DllCanUnloadNow@0
+ DllGetClassObject   = DllGetClassObject@12
+ DllRegisterServer   = DllRegisterServer@0
+ DllUnregisterServer = DllUnregisterServer@0
+
+</verb></tscreen>
+
+<item>
+In addition to creating a DLL, the <tt>--mk-dll</tt> option will also
+create an import library. The import library name is derived from the
+name of the DLL, as follows:
+
+<tscreen><verb>
+  DLL: HScool.dll  ==> import lib: libHScool_imp.a
+</verb></tscreen>
+
+The naming scheme may look a bit weird, but it has the purpose of
+allowing the co-existence of import libraries with ordinary static
+libraries (e.g., <tt>libHSfoo.a</tt> and <tt>libHSfoo_imp.a</tt>.
+
+Additionally, when the compiler driver is linking in non-static mode,
+it will rewrite occurrence of <tt>-lHSfoo</tt> on the command line to
+<tt>-lHSfoo_imp</tt>. By doing this for you, switching from non-static
+to static linking is simply a question of adding <tt>-static</tt> to
+your command line.
+
+</itemize>