Commit 5364ea8b authored by Duncan Coutts's avatar Duncan Coutts

Improve the user guide section on shared libs

Make it clear that Haskell code to be used by other Haskell code
must be built as a package.
parent 5b23f41c
......@@ -68,10 +68,72 @@ ghc --make -dynamic Main.hs
</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>
To build some Haskell modules into a shared library use the
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>
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
......@@ -98,39 +160,14 @@ ghc -dynamic -shared Foo.o -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>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment