summaryrefslogtreecommitdiff
path: root/docs/users_guide/shared_libs.xml
diff options
context:
space:
mode:
Diffstat (limited to 'docs/users_guide/shared_libs.xml')
-rw-r--r--docs/users_guide/shared_libs.xml269
1 files changed, 0 insertions, 269 deletions
diff --git a/docs/users_guide/shared_libs.xml b/docs/users_guide/shared_libs.xml
deleted file mode 100644
index 7d2b635d7e..0000000000
--- a/docs/users_guide/shared_libs.xml
+++ /dev/null
@@ -1,269 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<sect1 id="using-shared-libs">
- <title>Using shared libraries</title>
- <indexterm><primary>Shared libraries</primary><secondary>using</secondary></indexterm>
- <indexterm><primary>Dynamic libraries</primary><secondary>using</secondary></indexterm>
-
- <para>
- On some platforms GHC supports building Haskell code into shared
- libraries. Shared libraries are also sometimes known as dynamic
- libraries, in particular on Windows they are referred to as dynamic link
- libraries (DLLs).
- </para>
-
- <para>
- Shared libraries allow a single instance of some pre-compiled code to be
- shared between several programs. In contrast, with static linking the
- code is copied into each program. Using shared libraries can thus save
- disk space. They also allow a single copy of code to be shared in memory
- between several programs that use it. Shared libraries are often used as
- a way of structuring large projects, especially where different parts are
- written in different programming languages. Shared libraries are also
- commonly used as a plugin mechanism by various applications. This is
- particularly common on Windows using COM.
- </para>
-
- <para>
- In GHC version 6.12 building shared libraries is supported for Linux (on
- x86 and x86-64 architectures). GHC version 7.0 adds support on Windows
- (see <xref linkend="win32-dlls"/>), FreeBSD and OpenBSD (x86 and x86-64),
- Solaris (x86) and Mac OS X (x86 and PowerPC).
- </para>
-
- <para>
- Building and using shared libraries is slightly more complicated than
- building and using static libraries. When using Cabal much of the detail
- is hidden, just use <literal>--enable-shared</literal> when configuring a
- package to build it into a shared library, or to link it against other
- packages built as shared libraries. The additional complexity when
- building code is to distinguish whether the code will be used in a shared
- library or will use shared library versions of other packages it depends
- on. There is additional complexity when installing and distributing
- shared libraries or programs that use shared libraries, to ensure that
- all shared libraries that are required at runtime are present in suitable
- locations.
- </para>
-
- <sect2>
- <title>Building programs that use shared libraries</title>
- <para>
- To build a simple program and have it use shared libraries for the
- runtime system and the base libraries use the
- <literal>-dynamic</literal> flag:
-<programlisting>
-ghc --make -dynamic Main.hs
-</programlisting>
- This has two effects. The first is to compile the code in such a way
- that it can be linked against shared library versions of Haskell
- packages (such as base). The second is when linking, to link against
- the shared versions of the packages' libraries rather than the static
- versions. Obviously this requires that the packages were built with
- shared libraries. On supported platforms GHC comes with shared
- libraries for all the core packages, but if you install extra packages
- (e.g. with Cabal) then they would also have to be built with shared
- libraries (<literal>--enable-shared</literal> for Cabal).
- </para>
- </sect2>
-
- <sect2>
- <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. The reason for this is that
- 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 libraries a Haskell library can be treated just like any
- other shared library. 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
-</programlisting>
- As before, the <literal>-dynamic</literal> flag specifies that this
- library links against the shared library versions of the rts and base
- package. The <literal>-fPIC</literal> flag is required for all code
- that will end up in a shared library. The <literal>-shared</literal>
- flag specifies to make a shared library rather than a program. To make
- this clearer we can break this down into separate compilation and link
- steps:
-<programlisting>
-ghc -dynamic -fPIC -c Foo.hs
-ghc -dynamic -shared Foo.o -o libfoo.so
-</programlisting>
- In principle you can use <literal>-shared</literal> without
- <literal>-dynamic</literal> in the link step. That means to
- statically link the rts all the base libraries into your new shared
- library. This would make a very big, but standalone shared library.
- On most platforms however that would require all the static libraries
- to have been built with <literal>-fPIC</literal> so that the code is
- suitable to include into a shared library and we do not do that at the
- moment.
- </para>
- <para>
- <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 id="finding-shared-libs">
- <title>Finding shared libraries at runtime</title>
- <para>
- The primary difficulty with managing shared libraries is arranging
- things such that programs can find the libraries they need at runtime.
- The details of how this works varies between platforms, in particular
- the three major systems: Unix ELF platforms, Windows and Mac OS X.
- </para>
- <sect3 id="finding-shared-libs-unix">
- <title>Unix</title>
- <para>
- On Unix there are two mechanisms. Shared libraries can be installed
- into standard locations that the dynamic linker knows about. For
- example <literal>/usr/lib</literal> or
- <literal>/usr/local/lib</literal> on most systems. The other mechanism
- is to use a "runtime path" or "rpath" embedded into programs and
- libraries themselves. These paths can either be absolute paths or on at
- least Linux and Solaris they can be paths relative to the program or
- library itself. In principle this makes it possible to construct fully
- relocatable sets of programs and libraries.
- </para>
- <para>
- GHC has a <literal>-dynload</literal> linking flag to select the method
- that is used to find shared libraries at runtime. There are currently
- two modes:
- <variablelist>
- <varlistentry>
- <term>sysdep</term>
- <listitem>
- <para>
- A system-dependent mode. This is also the default mode. On Unix
- ELF systems this embeds
- <literal>RPATH</literal>/<literal>RUNPATH</literal> entries into the
- shared library or executable. In particular it uses absolute paths to
- where the shared libraries for the rts and each package can be found.
- This means the program can immediately be run and it will be able to
- find the libraries it needs. However it may not be suitable for
- deployment if the libraries are installed in a different location on
- another machine.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>deploy</term>
- <listitem>
- <para>
- This does not embed any runtime paths. It relies on the shared
- libraries being available in a standard location or in a
- directory given by the <literal>LD_LIBRARY_PATH</literal>
- environment variable.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- To use relative paths for dependent libraries on Linux and Solaris you
- can pass a suitable <literal>-rpath</literal> flag to the linker:
-<programlisting>
-ghc -dynamic Main.hs -o main -lfoo -L. -optl-Wl,-rpath,'$ORIGIN'
-</programlisting>
- This assumes that the library <literal>libfoo.so</literal> is in the
- current directory and will be able to be found in the same directory as
- the executable <literal>main</literal> once the program is deployed.
- Similarly it would be possible to use a subdirectory relative to the
- executable e.g. <literal>-optl-Wl,-rpath,'$ORIGIN/lib'</literal>.
- </para>
- <para>
- This relative path technique can be used with either of the two
- <literal>-dynload</literal> modes, though it makes most sense with the
- <literal>deploy</literal> mode. The difference is that with the
- <literal>deploy</literal> mode, the above example will end up with an ELF
- <literal>RUNPATH</literal> of just <literal>$ORIGIN</literal> while with
- the <literal>sysdep</literal> mode the <literal>RUNPATH</literal> will be
- <literal>$ORIGIN</literal> followed by all the library directories of all
- the packages that the program depends on (e.g. <literal>base</literal>
- and <literal>rts</literal> packages etc.) which are typically absolute
- paths. The unix tool <literal>readelf --dynamic</literal> is handy for
- inspecting the <literal>RPATH</literal>/<literal>RUNPATH</literal>
- entries in ELF shared libraries and executables.
- </para>
- </sect3>
- <sect3 id="finding-shared-libs-mac">
- <title>Mac OS X</title>
- <para>
- The standard assumption on Darwin/Mac OS 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>
- </sect3>
- </sect2>
-
-</sect1>
-
-<!-- Emacs stuff:
- ;;; Local Variables: ***
- ;;; sgml-parent-document: ("users_guide.xml" "book" "chapter" "sect1") ***
- ;;; ispell-local-dictionary: "british" ***
- ;;; End: ***
- -->