X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=docs%2Fusers_guide%2Fshared_libs.xml;h=5c258d4b9de99efa7ad18d906111ac1df6242be2;hb=b1cfe1372b27bd622bc6abd5da0e77a82633c068;hp=e2152d1818bb83fd38189899f224eac034a751ad;hpb=a7981216f157c0d7faac9e9acf98cf0351951a8d;p=ghc-hetmet.git diff --git a/docs/users_guide/shared_libs.xml b/docs/users_guide/shared_libs.xml index e2152d1..5c258d4 100644 --- a/docs/users_guide/shared_libs.xml +++ b/docs/users_guide/shared_libs.xml @@ -16,7 +16,7 @@ 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 + 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 @@ -24,12 +24,10 @@ - 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 - ). 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. + 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 ), FreeBSD and OpenBSD (x86 and x86-64), + Solaris (x86) and Mac OS X (x86 and PowerPC). @@ -59,7 +57,7 @@ ghc --make -dynamic Main.hs 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 + 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 @@ -68,10 +66,69 @@ ghc --make -dynamic Main.hs - Building shared libraries + Shared libraries for Haskell packages + + 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 --enable-shared + flag. + + + 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. + + + In particular Haskell shared libraries must 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 within the same + shared library (or main executable binary) differently from references + to symbols between 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 -dynamic, 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). + - To build some Haskell modules into a shared library use the + Most of the conventions GHC expects when using packages are described + in . In addition note that GHC + expects the .hi files to use the extension + .dyn_hi. The other requirements are the same as for + C libraries and are described below, in particular the use of the flags -dynamic, -fPIC and + -shared. + + + + + Shared libraries that export a C API + + 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. + + + 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 . 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. + + + To build Haskell modules that export a C API into a shared library use + the -dynamic, -fPIC and -shared flags: ghc --make -dynamic -shared -fPIC Foo.hs -o libfoo.so @@ -81,7 +138,7 @@ ghc --make -dynamic -shared -fPIC Foo.hs -o libfoo.so package. The -fPIC flag is required for all code that will end up in a shared library. The -shared 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 + this clearer we can break this down into separate compilation and link steps: ghc -dynamic -fPIC -c Foo.hs @@ -91,44 +148,17 @@ ghc -dynamic -shared Foo.o -o libfoo.so -dynamic 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 ). On most platforms however that would require all the static libraries to have been built with -fPIC so that the code is suitable to include into a shared library and we do not do that at the moment. - - - - Shared libraries that export a C API - 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. + Warning: 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. - - 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 . 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. - - - - - Shared libraries for Haskell packages - - 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 . - @@ -139,6 +169,8 @@ ghc -dynamic -shared Foo.o -o libfoo.so The details of how this works varies between platforms, in particular the three major systems: Unix ELF platforms, Windows and Mac OS X. + + Unix On Unix there are two mechanisms. Shared libraries can be installed into standard locations that the dynamic linker knows about. For @@ -147,26 +179,27 @@ ghc -dynamic -shared Foo.o -o libfoo.so 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 + library itself. In principle this makes it possible to construct fully relocatable sets of programs and libraries. GHC has a -dynload linking flag to select the method that is used to find shared libraries at runtime. There are currently - three modes: + two modes: sysdep 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. + ELF systems this embeds + RPATH/RUNPATH 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. @@ -181,21 +214,9 @@ ghc -dynamic -shared Foo.o -o libfoo.so - - wrapped - - - 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. - - - To use relative paths for dependent libraries on Linux and Solaris you - can use the deploy mode and pass suitable a -rpath - flag to the linker: + can pass a suitable -rpath flag to the linker: ghc -dynamic Main.hs -o main -lfoo -L. -optl-Wl,-rpath,'$ORIGIN' @@ -205,6 +226,37 @@ ghc -dynamic Main.hs -o main -lfoo -L. -optl-Wl,-rpath,'$ORIGIN' Similarly it would be possible to use a subdirectory relative to the executable e.g. -optl-Wl,-rpath,'$ORIGIN/lib'. + + This relative path technique can be used with either of the two + -dynload modes, though it makes most sense with the + deploy mode. The difference is that with the + deploy mode, the above example will end up with an ELF + RUNPATH of just $ORIGIN while with + the sysdep mode the RUNPATH will be + $ORIGIN followed by all the library directories of all + the packages that the program depends on (e.g. base + and rts packages etc.) which are typically absolute + paths. The unix tool readelf --dynamic is handy for + inspecting the RPATH/RUNPATH + entries in ELF shared libraries and executables. + + + + Mac OS X + + 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 + -dylib-install-name option (which passes + -install_name 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. + +