Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
GHC
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
0
Merge Requests
0
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Alex D
GHC
Commits
a7981216
Commit
a7981216
authored
Jul 04, 2009
by
Duncan Coutts
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new section on using shared libs
parent
cc8e41a3
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
214 additions
and
1 deletion
+214
-1
docs/users_guide/shared_libs.xml
docs/users_guide/shared_libs.xml
+210
-0
docs/users_guide/ug-ent.xml
docs/users_guide/ug-ent.xml
+1
-0
docs/users_guide/using.xml
docs/users_guide/using.xml
+3
-1
No files found.
docs/users_guide/shared_libs.xml
0 → 100644
View file @
a7981216
<?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 libraires 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 and there is partial support on Windows (see
<xref
linkend=
"win32-dlls"
/>
). The crucial difference in support on
Windows is that it is not currently possible to build each Haskell
package as a separate DLL, it is only possible to link an entire Haskell
program as one massive DLL.
</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 build 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>
Building shared libraries
</title>
<para>
To build some Haskell modules 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 compliation 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.
Indeed this is exactly what we must currently do on Windows where
-dynamic is not yet supported (see
<xref
linkend=
"win32-dlls"
/>
).
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>
</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>
</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>
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>
<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
libary 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
three modes:
<variablelist>
<varlistentry>
<term>
sysdep
</term>
<listitem>
<para>
A system-dependent mode. This is also the default mode. On Unix
ELF systems this embeds rpaths 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>
<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
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>
</sect2>
</sect1>
docs/users_guide/ug-ent.xml
View file @
a7981216
...
...
@@ -20,3 +20,4 @@
<!ENTITY utils SYSTEM "utils.xml" >
<!ENTITY win32-dll SYSTEM "win32-dlls.xml">
<!ENTITY ffi-chap SYSTEM "ffi-chap.xml">
<!ENTITY shared_libs SYSTEM "shared_libs.xml">
docs/users_guide/using.xml
View file @
a7981216
...
...
@@ -1795,7 +1795,9 @@ f "2" = 2
</sect1>
&phases;
&shared_libs;
<sect1
id=
"using-concurrent"
>
<title>
Using Concurrent Haskell
</title>
<indexterm><primary>
Concurrent Haskell
</primary><secondary>
using
</secondary></indexterm>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment