[project @ 1999-05-04 08:30:44 by sof]
[ghc-hetmet.git] / ghc / docs / users_guide / win32-dlls.sgml
1 %************************************************************************
2 %*                                                                      *
3 <sect>Building and using Win32 DLLs
4 <label id="win32-dlls">
5 <p>
6 <nidx>Dynamic link libraries, Win32</nidx>
7 <nidx>DLLs, Win32</nidx>
8 %*                                                                      *
9 %************************************************************************
10
11 On Win32 platforms, the compiler is capable of both producing and using
12 dynamic link libraries (DLLs) containing ghc-compiled code. This
13 section shows you how to make use of this facility.
14
15 %************************************************************************
16 %*                                                                      *
17 <sect1>Linking with DLLs
18 <label id="win32-dlls:link">
19 <p>
20 %*                                                                      *
21 %************************************************************************
22
23 The default on Win32 platforms is to link applications in such a way
24 that the executables will use the Prelude and system libraries DLLs,
25 rather than contain (large chunks of) them. This is transparent at the
26 command-line, so 
27
28 <tscreen><verb>
29 sh$ cat main.hs
30 module Main where
31 main = putStrLn "hello, world!"
32 sh$ ghc -o main main.hs
33 ghc: module version changed to 1; reason: no old .hi file
34 sh$ strip main.exe
35 sh$ ls -l main.exe
36 -rwxr-xr-x   1 544      everyone     6144 May  3 17:11 main.exe*
37 sh$ ./main
38 hello, world!
39 sh$ 
40 </verb></tscreen>
41
42 will give you a binary as before, but the <tt>main.exe</tt> generated
43 will use the Prelude and RTS DLLs instead.
44
45 6K for a <tt>"hello, world"</tt> application - not bad, huh? :-)
46
47 %************************************************************************
48 %*                                                                      *
49 <sect1>Not linking with DLLs
50 <label id="win32-dlls:linking-static">
51 <nidx>-static option (Win32)</nidx>
52 <p>
53 %*                                                                      *
54 %************************************************************************
55
56 If you want to build an executable that doesn't depend on any
57 ghc-compiled DLLs, use the <tt>-static</tt> option to link in
58 the code statically.
59
60 Notice that you cannot mix code that has been compiled with
61 <tt>-static</tt> and not, so you have to use the <tt>-static</tt>
62 option on all the Haskell modules that make up your application.
63
64 %************************************************************************
65 %*                                                                      *
66 <sect1>Creating a DLL
67 <label id="win32-dlls:create">
68 <p>
69 <nidx>Creating a Win32 DLL</nidx>
70 <nidx>--mk-dll</nidx>
71 %*                                                                      *
72 %************************************************************************
73
74 Sealing up your Haskell library inside a DLL is quite straightforward;
75 compile up the object files that make up the library, and then build
76 the DLL by issuing the following command:
77
78 <tscreen><verb>
79 sh$ ghc --mk-dll -o HSsuper.dll A.o Super.o B.o libmine.a -lgdi32
80 </verb></tscreen>
81
82 By feeding the ghc compiler driver the option <tt>--mk-dll</tt>, it
83 will build a DLL rather than produce an executable. The DLL will
84 consist of all the object files and archives given on the command
85 line.
86
87 A couple of things to notice:
88
89 <itemize>
90 <item>
91 When compiling the module <tt>A</tt>, the code emitted by the compiler
92 differs depending on whether or not the functions and data it is
93 importing from other Haskell modules correspond to symbols that are
94 packaged up in a ghc-compiled DLL. To resolve whether such imports are
95 'DLL imports' or not, the following rules are used:
96
97 <itemize>
98 <item>
99 If the compiler imports from a module that's in the same directory as
100 the one being compiled, it is assumed to not belong to a different DLL
101 (or executable) than the module being processed, so none of the
102 same-directory imports are considered 'DLL imports'.
103
104 <item>
105 If a directory contains the (probably empty) file
106 <tt>dLL_ifs.hi</tt>, the code corresponding to the interface
107 files found in that directory are assumed to live in a DLL
108 separate from the one being compiled. 
109
110 Notice that the first rule takes precedence over this one, so if
111 you're compiling a module that imports from a Haskell module whose
112 interface file live in the same directory, <em>and</em> that directory
113 also contains the file <tt>dLL_ifs.hi</tt>, the import is still not
114 being considered to be a 'DLL import'.
115
116 <item>
117 If compiling with the option <tt>-static</tt>, the previous rule
118 is disabled.
119 </itemize>
120
121 So, in short, after having built your Haskell DLL, make sure you
122 create the file <tt>dLL_ifs.hi</tt> in the directory that contains
123 its interface files. If you don't, Haskell code that calls upon entry
124 points in that DLL, will do so incorrectly, and a crash will result.
125 (it is unfortunate that this isn't currently caught at compile-time).
126
127 <item>
128 By default, the entry points of all the object files will
129 be exported from the DLL when using <tt>--mk-dll</tt>. Should you want
130 to constrain this, you can specify the <em>module definition file</em>
131 to use on the command line as follows:
132
133 <tscreen><verb>
134 sh$ ghc --mk-dll -o .... -optdll--def -optdllMyDef.def
135 </verb></tscreen>
136
137 See Microsoft documentation for details, but a module definition file
138 simply lists what entry points you want to export. Here's one that's
139 suitable when building a Haskell COM server DLL:
140
141 <tscreen><verb>
142 EXPORTS
143  DllCanUnloadNow     = DllCanUnloadNow@0
144  DllGetClassObject   = DllGetClassObject@12
145  DllRegisterServer   = DllRegisterServer@0
146  DllUnregisterServer = DllUnregisterServer@0
147
148 </verb></tscreen>
149
150 <item>
151 In addition to creating a DLL, the <tt>--mk-dll</tt> option will also
152 create an import library. The import library name is derived from the
153 name of the DLL, as follows:
154
155 <tscreen><verb>
156   DLL: HScool.dll  ==> import lib: libHScool_imp.a
157 </verb></tscreen>
158
159 The naming scheme may look a bit weird, but it has the purpose of
160 allowing the co-existence of import libraries with ordinary static
161 libraries (e.g., <tt>libHSfoo.a</tt> and <tt>libHSfoo_imp.a</tt>.
162
163 Additionally, when the compiler driver is linking in non-static mode,
164 it will rewrite occurrence of <tt>-lHSfoo</tt> on the command line to
165 <tt>-lHSfoo_imp</tt>. By doing this for you, switching from non-static
166 to static linking is simply a question of adding <tt>-static</tt> to
167 your command line.
168
169 </itemize>