diff --git a/ghc/docs/users_guide/win32-dlls.sgml b/ghc/docs/users_guide/win32-dlls.sgml new file mode 100644 index 0000000000000000000000000000000000000000..8c3090bea2788a0185133ba27f85ea9477985993 --- /dev/null +++ b/ghc/docs/users_guide/win32-dlls.sgml @@ -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>