Reorganisation of the source tree
[ghc-hetmet.git] / docs / users_guide / win32-dlls.xml
diff --git a/docs/users_guide/win32-dlls.xml b/docs/users_guide/win32-dlls.xml
new file mode 100644 (file)
index 0000000..959f7ce
--- /dev/null
@@ -0,0 +1,493 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<chapter id="win32">
+<title>Running GHC on Win32 systems</title>
+
+<sect1>
+<title>
+Starting GHC on Win32 platforms</title>
+
+<para>
+The installer that installs GHC on Win32 also sets up the file-suffix associations
+for ".hs" and ".lhs" files so that double-clicking them starts <command>ghci</command>.
+</para>
+<para>
+Be aware of that <command>ghc</command> and <command>ghci</command> do
+require filenames containing spaces to be escaped using quotes:
+<programlisting>
+  c:\ghc\bin\ghci "c:\\Program Files\\Haskell\\Project.hs"
+</programlisting>
+If the quotes are left off in the above command, <command>ghci</command> will
+interpret the filename as two, "c:\\Program" and "Files\\Haskell\\Project.hs".
+</para>
+
+<!-- not clear whether there are current editions of Win32 OSes that
+     doesn't do this by default.
+
+<para> Solution: don't use "Open With...", avoid spaces in file names, 
+or fiddle with the appropriate registry setting:
+<programlisting>
+  HKEY_CLASSES_ROOT\Unknown\shell\openas\command
+</programlisting>
+Notice how the "%1" argument is quoted (or not).
+</para>
+<para> This problem doesn't occur when double-clicking.
+</para>
+-->
+
+</sect1>
+
+<sect1>
+<title>
+Interacting with the terminal</title>
+
+<para>By default GHC builds applications that open a console window when they start.
+If you want to build a GUI-only application, with no console window, use the flag
+<literal>-optl-mwindows</literal> in the link step.
+</para>
+
+<para>       <emphasis>Warning:</emphasis> Windows GUI-only programs have no
+        stdin, stdout or stderr so using the ordinary Haskell
+        input/output functions will cause your program to fail with an
+        IO exception, such as:
+<screen>
+      Fail: &lt;stdout&gt;: hPutChar: failed (Bad file descriptor)
+</screen>
+        However using Debug.Trace.trace is alright because it uses
+        Windows debugging output support rather than stderr.</para>
+
+<para>For some reason, Mingw ships with the <literal>readline</literal> library,
+but not with the <literal>readline</literal> headers. As a result, GHC (like Hugs) does not
+use <literal>readline</literal> for interactive input on Windows.
+You can get a close simulation by using an emacs shell buffer!
+</para>
+
+</sect1>
+
+<sect1>
+<title>
+Differences in library behaviour </title>
+
+<para>
+Some of the standard Haskell libraries behave slightly differently on Windows.
+
+<itemizedlist>
+<listitem> <para>
+On Windows, the '<literal>^Z</literal>' character is interpreted as an
+end-of-file character, so if you read a file containing this character
+the file will appear to end just before it. To avoid this,
+use <literal>IOExts.openFileEx</literal> to open a file in binary
+(untranslated) mode or change an already opened file handle into
+binary mode using <literal>IOExts.hSetBinaryMode</literal>. The
+<literal>IOExts</literal> module is part of the
+<literal>lang</literal> package.
+</para>
+</listitem>
+</itemizedlist>
+</para>
+</sect1>
+
+<sect1>
+<title>
+Using GHC (and other GHC-compiled executables) with cygwin</title>
+
+<sect2>
+<title>Background</title> <para>The cygwin tools aim to provide a
+unix-style API on top of the windows libraries, to facilitate ports of
+unix software to windows. To this end, they introduce a unix-style
+directory hierarchy under some root directory (typically
+<filename>/</filename> is <filename>C:\cygwin\</filename>). Moreover,
+everything built against the cygwin API (including the cygwin tools
+and programs compiled with cygwin's ghc) will see / as the root of
+their file system, happily pretending to work in a typical unix
+environment, and finding things like <filename>/bin</filename> and <filename>/usr/include</filename> without
+ever explicitly bothering with their actual location on the windows
+system (probably <filename>C:\cygwin\bin</filename> and <filename>C:\cygwin\usr\include</filename>).
+</para>
+</sect2>
+
+<sect2><title>The problem</title>
+<para>GHC, by default, no longer depends on cygwin, but is a native
+windows program. It is built using mingw, and it uses mingw's ghc
+while compiling your Haskell sources (even if you call it from
+cygwin's bash), but what matters here is that - just like any other
+normal windows program - neither GHC nor the executables it produces
+are aware of cygwin's pretended unix hierarchy. GHC will happily
+accept either '/' or '\' as path separators, but it won't know where
+to find <filename>/home/joe/Main.hs</filename> or <filename>/bin/bash</filename> 
+or the like. This causes all
+kinds of fun when GHC is used from within cygwin's bash, or in
+make-sessions running under cygwin.
+</para>
+</sect2>
+
+<sect2><title>Things to do</title>
+<itemizedlist>
+<listitem>
+<para> Don't use absolute paths in make, configure &amp; co if there is any chance 
+  that those might be passed to GHC (or to GHC-compiled programs). Relative
+  paths are fine because cygwin tools are happy with them and GHC accepts 
+  '/' as path-separator. And relative paths don't depend on where cygwin's
+  root directory is located, or on which partition or network drive your source
+  tree happens to reside, as long as you 'cd' there first.
+</para></listitem>
+
+<listitem>
+<para> If you have to use absolute paths (beware of the innocent-looking
+  <literal>ROOT=`pwd`</literal> in makefile hierarchies or configure scripts), cygwin provides
+  a tool called <command>cygpath</command> that can convert cygwin's unix-style paths to their
+  actual windows-style counterparts. Many cygwin tools actually accept
+  absolute windows-style paths (remember, though, that you either need 
+  to escape '\' or convert '\' to '/'), so you should be fine just using those 
+  everywhere. If you need to use tools that do some kind of path-mangling 
+  that depends on unix-style paths (one fun example is trying to interpret ':' 
+  as a separator in path lists..), you can still try to convert paths using 
+  <command>cygpath</command> just before they are passed to GHC and friends.
+</para></listitem>
+  
+<listitem>
+<para> If you don't have <command>cygpath</command>, you probably don't have cygwin and hence
+  no problems with it... unless you want to write one build process for several
+  platforms. Again, relative paths are your friend, but if you have to use
+  absolute paths, and don't want to use different tools on different platforms,
+  you can simply write a short Haskell program to print the current directory
+   (thanks to George Russell for this idea): compiled with GHC, this will give 
+  you the view of the file system that GHC depends on (which will differ 
+  depending on whether GHC is compiled with cygwin's gcc or mingw's
+  gcc or on a real unix system..) - that little program can also deal with 
+  escaping '\' in paths. Apart from the banner and the startup time, 
+  something like this would also do:
+<programlisting>
+  $ echo "Directory.getCurrentDirectory >>= putStrLn . init . tail . show " | ghci
+</programlisting>
+</para></listitem>
+</itemizedlist>
+</sect2>
+</sect1>
+
+
+<sect1 id="win32-dlls">
+<title>Building and using Win32 DLLs
+</title>
+
+<para>
+<emphasis>Making Haskell libraries into DLLs doesn't work on Windows at the
+moment; however, all the machinery is
+still there. If you're interested, contact the GHC team. Note that
+building an entire Haskell application as a single DLL is still supported: it's
+       just multi-DLL Haskell programs that don't work.  The Windows
+       distribution of GHC contains static libraries only.</emphasis></para>
+
+<!--
+<para>
+<indexterm><primary>Dynamic link libraries, Win32</primary></indexterm>
+<indexterm><primary>DLLs, Win32</primary></indexterm>
+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.
+</para>
+
+<para>
+Until recently, <command>strip</command> didn't work reliably on DLLs, so you
+should test your version with care, or make sure you have the latest
+binutils. Unfortunately, we don't know exactly which version of binutils
+cured the problem (it was supposedly fixed some years ago).
+</para>
+
+
+<sect2 id="win32-dlls-link">
+<title>Linking with DLLs</title>
+
+<para>
+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 
+</para>
+
+<para>
+<screen>
+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     4608 May  3 17:11 main.exe*
+sh$ ./main
+hello, world!
+sh$ 
+</screen>
+</para>
+
+<para>
+will give you a binary as before, but the <filename>main.exe</filename>
+generated will use the Prelude and RTS DLLs instead of linking them in
+statically.
+</para>
+
+<para>
+4K for a <literal>"hello, world"</literal> application&mdash;not bad, huh? :-)
+</para>
+
+</sect2>
+
+<sect2 id="win32-dlls-linking-static">
+<title>Not linking with DLLs
+<indexterm><primary>-static option (Win32)</primary></indexterm></title>
+
+<para>
+If you want to build an executable that doesn't depend on any
+ghc-compiled DLLs, use the <option>-static</option> option to link in
+the code statically.
+</para>
+
+<para>
+Notice that you cannot mix code that has been compiled with
+<option>-static</option> and not, so you have to use the <option>-static</option>
+option on all the Haskell modules that make up your application.
+</para>
+
+</sect2>
+-->
+
+<sect2 id="win32-dlls-create">
+<title>Creating a DLL</title>
+
+<para>
+<indexterm><primary>Creating a Win32 DLL</primary></indexterm>
+<indexterm><primary>&ndash;&ndash;mk-dll</primary></indexterm>
+Sealing up your Haskell library inside a DLL is straightforward;
+compile up the object files that make up the library, and then build
+the DLL by issuing a command of the form:
+</para>
+
+<para>
+<screen>
+ghc &ndash;&ndash;mk-dll -o foo.dll bar.o baz.o wibble.a -lfooble
+</screen>
+</para>
+
+<para>
+By feeding the ghc compiler driver the option <option>&ndash;&ndash;mk-dll</option>, 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.
+</para>
+
+<!--
+<para>
+To create a `static' DLL, i.e. one that does not depend on the GHC DLLs,
+use the <option>-static</option> when compiling up your Haskell code and
+building the DLL.
+</para>
+-->
+
+<para>
+A couple of things to notice:
+</para>
+
+<para>
+
+<itemizedlist>
+<!--
+<listitem>
+<para>
+Since DLLs correspond to packages (see <xref linkend="packages"/>) you need
+to use <option>-package-name dll-name</option> when compiling modules that
+belong to a DLL if you're going to call them from Haskell. Otherwise, Haskell
+code that calls entry points in that DLL will do so incorrectly, and crash.
+For similar reasons, you can only compile a single module tree into a DLL,
+as <function>startupHaskell</function> needs to be able to call its
+initialisation function, and only takes one such argument (see <xref
+linkend="win32-dlls-foreign"/>). Hence the modules
+you compile into a DLL must have a common root.
+</para>
+</listitem>
+-->
+
+<listitem>
+<para>
+By default, the entry points of all the object files will be exported from
+the DLL when using <option>&ndash;&ndash;mk-dll</option>. Should you want to constrain
+this, you can specify the <emphasis>module definition file</emphasis> to use
+on the command line as follows:
+
+<screen>
+ghc &ndash;&ndash;mk-dll -o .... -optdll&ndash;&ndash;def -optdllMyDef.def
+</screen>
+
+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:
+
+<programlisting>
+EXPORTS
+ DllCanUnloadNow     = DllCanUnloadNow@0
+ DllGetClassObject   = DllGetClassObject@12
+ DllRegisterServer   = DllRegisterServer@0
+ DllUnregisterServer = DllUnregisterServer@0
+</programlisting>
+</para>
+</listitem>
+
+<listitem>
+<para>
+In addition to creating a DLL, the <option>&ndash;&ndash;mk-dll</option> option also
+creates an import library. The import library name is derived from the
+name of the DLL, as follows:
+
+<programlisting>
+DLL: HScool.dll  ==&#62; import lib: libHScool_imp.a
+</programlisting>
+
+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.,
+<filename>libHSfoo.a</filename> and
+<filename>libHSfoo&lowbar;imp.a</filename>.
+
+Additionally, when the compiler driver is linking in non-static mode, it
+will rewrite occurrence of <option>-lHSfoo</option> on the command line to
+<option>-lHSfoo&lowbar;imp</option>. By doing this for you, switching from
+non-static to static linking is simply a question of adding
+<option>-static</option> to your command line.
+
+</para>
+</listitem>
+</itemizedlist>
+</para>
+
+</sect2>
+
+
+<sect2 id="win32-dlls-foreign">
+<title>Making DLLs to be called from other languages</title>
+
+<para>
+
+If you want to package up Haskell code to be called from other languages,
+such as Visual Basic or C++, there are some extra things it is useful to
+know. The dirty details are in the <emphasis>Foreign Function
+Interface</emphasis> definition, but it can be tricky to work out how to
+combine this with DLL building, so here's an example:
+
+</para>
+
+<itemizedlist>
+
+<listitem>
+<para>
+Use <literal>foreign export</literal> declarations to export the Haskell
+functions you want to call from the outside. For example,
+
+<programlisting>
+module Adder where
+
+adder :: Int -> Int -> IO Int  &ndash;&ndash; gratuitous use of IO
+adder x y = return (x+y)
+
+foreign export stdcall adder :: Int -> Int -> IO Int
+</programlisting>
+</para>
+</listitem>
+
+<listitem>
+<para>
+Compile it up:
+
+<screen>
+ghc -c adder.hs -fglasgow-exts
+</screen>
+  
+This will produce two files, adder.o and adder_stub.o
+</para>
+</listitem>
+
+<listitem>
+<para>
+compile up a <function>DllMain()</function> that starts up the Haskell
+RTS-&ndash;&ndash;a possible implementation is:
+
+<programlisting>
+#include &lt;windows.h&gt;
+#include &lt;Rts.h&gt;
+
+extern void__stginit_Adder(void);
+
+static char* args[] = { "ghcDll", NULL };
+                       /* N.B. argv arrays must end with NULL */
+BOOL
+STDCALL
+DllMain
+   ( HANDLE hModule
+   , DWORD reason
+   , void* reserved
+   )
+{
+  if (reason == DLL_PROCESS_ATTACH) {
+      /* By now, the RTS DLL should have been hoisted in, but we need to start it up. */
+      startupHaskell(1, args, __stginit_Adder);
+      return TRUE;
+  }
+  return TRUE;
+}
+</programlisting>
+
+Here, <literal>Adder</literal> is the name of the root module in the module
+tree (as mentioned above, there must be a single root module, and hence a
+single module tree in the DLL).
+
+Compile this up:
+
+<screen>
+ghc -c dllMain.c
+</screen>
+</para>
+</listitem>
+
+<listitem>
+<para>
+Construct the DLL:
+
+<screen>
+ghc &ndash;&ndash;mk-dll -o adder.dll adder.o adder_stub.o dllMain.o
+</screen>
+
+</para>
+</listitem>
+
+<listitem>
+<para>
+Start using <function>adder</function> from VBA-&ndash;&ndash;here's how I would
+<constant>Declare</constant> it:
+
+<programlisting>
+Private Declare Function adder Lib "adder.dll" Alias "adder@8"
+      (ByVal x As Long, ByVal y As Long) As Long
+</programlisting>
+
+Since this Haskell DLL depends on a couple of the DLLs that come with GHC,
+make sure that they are in scope/visible.
+</para>
+
+<para>
+Building statically linked DLLs is the same as in the previous section: it
+suffices to add <option>-static</option> to the commands used to compile up
+the Haskell source and build the DLL.
+</para>
+
+</listitem>
+
+</itemizedlist>
+
+</sect2>
+
+</sect1>
+</chapter>
+
+<!-- Emacs stuff:
+     ;;; Local Variables: ***
+     ;;; mode: xml ***
+     ;;; sgml-parent-document: ("users_guide.xml" "book" "chapter") ***
+     ;;; End: ***
+ -->