</sect2>
<sect2>
- <title>Building shared libraries</title>
+ <title>Shared libraries for Haskell packages</title>
+ <para>
+ You can build Haskell code into a shared library and make a package to be
+ used by other Haskell programs. The easiest way is using Cabal, simply
+ configure the Cabal package with the <literal>--enable-shared</literal>
+ flag.
+ </para>
+ <para>
+ If you want to do the steps manually or are writing your own build
+ system then there are certain conventions that must be followed. Building
+ a shared library that exports Haskell code, to be used by other Haskell
+ code is a bit more complicated than it is for one that exports a C API
+ and will be used by C code. If you get it wrong you will usually end up
+ with linker errors.
+ </para>
+ <para>
+ In particular Haskell shared libraries <emphasis>must</emphasis> be
+ made into packages. You cannot freely assign which modules go in which
+ shared libraries. The Haskell shared libraries must match the package
+ boundaries. Most of the conventions GHC expects when using packages are
+ described in <xref linkend="building-packages"/>.
+ </para>
+ <para>
+ GHC handles references to symbols <emphasis>within</emphasis> the same
+ shared library (or main executable binary) differently from references
+ to symbols <emphasis>between</emphasis> different shared libraries. GHC
+ needs to know for each imported module if that module lives locally in
+ the same shared lib or in a separate shared lib. The way it does this
+ is by using packages. When using <literal>-dynamic</literal>, a module
+ from a separate package is assumed to come from a separate shared lib,
+ while modules from the same package (or the default "main" package) are
+ assumed to be within the same shared lib (or main executable binary).
+ </para>
<para>
- To build some Haskell modules into a shared library use the
+ Most of the conventions GHC expects when using packages are described
+ in <xref linkend="building-packages"/>. In addition note that GHC
+ expects the <literal>.hi</literal> files to use the extension
+ <literal>.dyn_hi</literal>. The other requirements are the same as for
+ C libraries and are described below, in particular the use of the flags
<literal>-dynamic</literal>, <literal>-fPIC</literal> and
+ <literal>-shared</literal>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Shared libraries that export a C API</title>
+ <para>
+ Building Haskell code into a shared library is a good way to include
+ Haskell code in a larger mixed-language project. While with static
+ linking it is recommended to use GHC to perform the final link step,
+ with shared libaries a Haskell library can be treated just like any
+ other shared libary. The linking can be done using the normal system C
+ compiler or linker.
+ </para>
+ <para>
+ It is possible to load shared libraries generated by GHC in other
+ programs not written in Haskell, so they are suitable for using as
+ plugins. Of course to construct a plugin you will have to use the FFI
+ to export C functions and follow the rules about initialising the RTS.
+ See <xref linkend="ffi-library"/>. In particular you will probably want
+ to export a C function from your shared library to initialise the
+ plugin before any Haskell functions are called.
+ </para>
+ <para>
+ To build Haskell modules that export a C API into a shared library use
+ the <literal>-dynamic</literal>, <literal>-fPIC</literal> and
<literal>-shared</literal> flags:
<programlisting>
ghc --make -dynamic -shared -fPIC Foo.hs -o libfoo.so
suitable to include into a shared library and we do not do that at the
moment.
</para>
- </sect2>
-
- <sect2>
- <title>Shared libraries that export a C API</title>
- <para>
- Building Haskell code into a shared library is a good way to include
- Haskell code in a larger mixed-language project. While with static
- linking it is recommended to use GHC to perform the final link step,
- with shared libaries a Haskell library can be treated just like any
- other shared libary. The linking can be done using the normal system C
- compiler or linker.
- </para>
<para>
- It is possible to load shared libraries generated by GHC in other
- programs not written in Haskell, so they are suitable for using as
- plugins. Of course to construct a plugin you will have to use the FFI
- to export C functions and follow the rules about initialising the RTS.
- See <xref linkend="ffi-library"/>. In particular you will probably want
- to export a C function from your shared library to initialise the
- plugin before any Haskell functions are called.
+ <emphasis>Warning:</emphasis> if your shared library exports a Haskell
+ API then you cannot directly link it into another Haskell program and
+ use that Haskell API. You will get linker errors. You must instead make
+ it into a package as described in the section above.
</para>
</sect2>
- <sect2>
- <title>Shared libraries for Haskell packages</title>
- <para>
- When building Haskell packages as shared libraries to be used by other
- Haskell programs there are certain conventions that must be followed.
- These are handled by Cabal but for the details see <xref
- linkend="building-packages"/>.
- </para>
- </sect2>
-
<sect2 id="finding-shared-libs">
<title>Finding shared libraries at runtime</title>
<para>
</para>
</listitem>
</varlistentry>
- <varlistentry>
- <term>wrapped</term>
- <listitem>
- <para>
- This mode generates a wrapper program which in turn calls the
- real program (in the same directory but with a .dyn extension)
- in such a way that it can find the shared libraries that it
- needs. At the current time this mode is somewhat experimental.
- </para>
- </listitem>
- </varlistentry>
</variablelist>
To use relative paths for dependent libraries on Linux and Solaris you
can use the <literal>deploy</literal> mode and pass suitable a -rpath
Similarly it would be possible to use a subdirectory relative to the
executable e.g. <literal>-optl-Wl,-rpath,'$ORIGIN/lib'</literal>.
</para>
+ <para>
+ The standard assumption on Darwin/MacOS X is that dynamic libraries will
+ be stamped at build time with an "install name", which is the full
+ ultimate install path of the library file. Any libraries or executables
+ that subsequently link against it (even if it hasn't been installed yet)
+ will pick up that path as their runtime search location for it. When
+ compiling with ghc directly, the install name is set by default to the
+ location where it is built. You can override this with the
+ <literal>-dylib-install-name</literal> option (which passes
+ <literal>-install_name</literal> to the Apple linker). Cabal does this
+ for you. It automatically sets the install name for dynamic libraries to
+ the absolute path of the ultimate install location.
+ </para>
</sect2>
</sect1>