[project @ 2003-08-06 15:26:02 by simonpj]
[ghc-hetmet.git] / ghc / docs / users_guide / win32-dlls.sgml
index 2679979..cdaad9c 100644 (file)
@@ -1,4 +1,160 @@
-<Chapter id="win32-dlls">
+<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>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 & 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>
 
@@ -18,7 +174,7 @@ cured the problem (it was supposedly fixed some years ago).
 </Para>
 
 
-<Sect1 id="win32-dlls-link">
+<Sect2 id="win32-dlls-link">
 <Title>Linking with DLLs
 </Title>
 
@@ -52,12 +208,12 @@ statically.
 </Para>
 
 <Para>
-4K for a <Literal>"hello, world"</Literal> application---not bad, huh? :-)
+4K for a <Literal>"hello, world"</Literal> application&mdash;not bad, huh? :-)
 </Para>
 
-</Sect1>
+</Sect2>
 
-<Sect1 id="win32-dlls-linking-static">
+<Sect2 id="win32-dlls-linking-static">
 <Title>Not linking with DLLs
 <IndexTerm><Primary>-static option (Win32)</Primary></IndexTerm></Title>
 
@@ -73,15 +229,20 @@ Notice that you cannot mix code that has been compiled with
 option on all the Haskell modules that make up your application.
 </Para>
 
-</Sect1>
+</Sect2>
 
-<Sect1 id="win32-dlls-create">
+<Sect2 id="win32-dlls-create">
 <Title>Creating a DLL
 </Title>
 
 <Para>
+<emphasis>Making libraries into DLLs doesn't work on Windows at the
+moment (and is no longer supported); however, all the machinery is
+still there. If you're interested, contact the GHC team. Note that
+building an entire Haskell application as a DLL is still supported
+(it's just inter-DLL Haskell calls that don't work).</emphasis>
 <IndexTerm><Primary>Creating a Win32 DLL</Primary></IndexTerm>
-<IndexTerm><Primary>--mk-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:
@@ -89,12 +250,12 @@ the DLL by issuing a command of the form:
 
 <Para>
 <Screen>
-ghc --mk-dll -o foo.dll bar.o baz.o wibble.a -lfooble
+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>--mk-dll</Option>, it
+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.
@@ -130,12 +291,12 @@ you compile into a DLL must have a common root.
 <ListItem>
 <Para>
 By default, the entry points of all the object files will be exported from
-the DLL when using <Option>--mk-dll</Option>. Should you want to constrain
+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 --mk-dll -o .... -optdll--def -optdllMyDef.def
+ghc &ndash;&ndash;mk-dll -o .... -optdll--def -optdllMyDef.def
 </Screen>
 
 See Microsoft documentation for details, but a module definition file
@@ -154,7 +315,7 @@ EXPORTS
 
 <ListItem>
 <Para>
-In addition to creating a DLL, the <Option>--mk-dll</Option> option also
+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:
 
@@ -178,10 +339,10 @@ non-static to static linking is simply a question of adding
 </ItemizedList>
 </Para>
 
-</Sect1>
+</Sect2>
 
 
-<Sect1 id="win32-dlls-foreign">
+<Sect2 id="win32-dlls-foreign">
 <Title>Making DLLs to be called from other languages</Title>
 
 <Para>
@@ -227,13 +388,13 @@ This will produce two files, adder.o and adder_stub.o
 <ListItem>
 <Para>
 compile up a <Function>DllMain()</Function> that starts up the Haskell
-RTS---a possible implementation is:
+RTS-&ndash;&ndash;a possible implementation is:
 
 <ProgramListing>
 #include &lt;windows.h&gt;
 #include &lt;Rts.h&gt;
 
-EXTFUN(__init_Adder);
+EXTFUN(__stginit_Adder);
 
 static char* args[] = { "ghcDll", NULL };
                        /* N.B. argv arrays must end with NULL */
@@ -247,7 +408,7 @@ DllMain
 {
   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, __init_Adder);
+      startupHaskell(1, args, __stginit_Adder);
       return TRUE;
   }
   return TRUE;
@@ -261,7 +422,7 @@ single module tree in the DLL).
 Compile this up:
 
 <Screen>
-gcc -c dllMain.c
+ghc -c dllMain.c
 </Screen>
 </Para>
 </ListItem>
@@ -271,7 +432,7 @@ gcc -c dllMain.c
 Construct the DLL:
 
 <Screen>
-ghc --mk-dll -o adder.dll adder.o adder_stub.o dllMain.o
+ghc &ndash;&ndash;mk-dll -o adder.dll adder.o adder_stub.o dllMain.o
 </Screen>
 
 </Para>
@@ -279,7 +440,7 @@ ghc --mk-dll -o adder.dll adder.o adder_stub.o dllMain.o
 
 <ListItem>
 <Para>
-Start using <Function>adder</Function> from VBA---here's how I would
+Start using <Function>adder</Function> from VBA-&ndash;&ndash;here's how I would
 <Constant>Declare</Constant> it:
 
 <ProgramListing>
@@ -301,8 +462,9 @@ the Haskell source and build the DLL.
 
 </ItemizedList>
 
-</Sect1>
+</Sect2>
 
+</sect1>
 </Chapter>
 
 <!-- Emacs stuff: