From f81df3c6e23b8d7d02eacca3d40974a45c7eb6d6 Mon Sep 17 00:00:00 2001 From: Clemens Fruhwirth Date: Fri, 14 Sep 2007 20:45:38 +0000 Subject: [PATCH] Add documentation about -shared, shared library name mangling, and a xrefs --- docs/users_guide/packages.xml | 174 +++++++++++++++++++++++------------------ docs/users_guide/phases.xml | 43 ++++++++-- 2 files changed, 132 insertions(+), 85 deletions(-) diff --git a/docs/users_guide/packages.xml b/docs/users_guide/packages.xml index 1de51a9..1423cb5 100644 --- a/docs/users_guide/packages.xml +++ b/docs/users_guide/packages.xml @@ -77,24 +77,36 @@ exposed-modules: Network.BSD, - This option causes the installed package P to be - exposed. The package P can be specified - in full with its version number - (e.g. network-1.0) or the version number can be - omitted if there is only one version of the package - installed. - - If there are multiple versions of P - installed, then all other versions will become hidden. + This option causes the installed + package P to be exposed. The + package P can be specified in + full with its version number + (e.g. network-1.0) or the version + number can be omitted if there is only one version of the + package installed. If there are multiple versions + of P installed, then all other + versions will become hidden. The - option also causes package P to be - linked into the resulting executable. In - mode and GHCi, the compiler - normally determines which packages are required by the current - Haskell modules, and links only those. In batch mode however, the - dependency information isn't available, and explicit - options must be given when linking. + option also causes package P to + be linked into the resulting executable or shared + object. Whether a packages' library is linked statically + or dynamically is controlled by the flag + pair /. + + In mode + and mode (see + ), the compiler normally + determines which packages are required by the current + Haskell modules, and links only those. In batch mode + however, the dependency information isn't available, and + explicit + options must be given when linking. The one other time you might need to use + to force linking a package is + when the package does not contain any Haskell modules (it + might contain a C library only, for example). In that + case, GHC will never discover a dependency on it, so it + has to be mentioned explicitly. For example, to link a program consisting of objects Foo.o and Main.o, where @@ -106,18 +118,7 @@ exposed-modules: Network.BSD, The same flag is necessary even if we compiled the modules from source, because GHC still reckons it's in batch mode: -$ ghc -o myprog Foo.hs Main.hs -package network - - In --make and --interactive - modes (), however, GHC figures out the - packages required for linking without further assistance. - - The one other time you might need to use - to force linking a package is when the - package does not contain any Haskell modules (it might contain a C - library only, for example). In that case, GHC - will never discover a dependency on it, so it has to be mentioned - explicitly. +$ ghc -o myprog Foo.hs Main.hs -package network @@ -348,65 +349,84 @@ $ export GHC_PACKAGE_PATH=$HOME/.my-ghc-packages.conf: lot of configuration, then you might have to fall back to the low-level mechanisms, so a few hints for those brave souls follow. + You need to build an "installed package info" file for + passing to ghc-pkg when installing your + package. The contents of this file are described in + . + + The Haskell code in a package may be built into one or more + archive libraries (e.g. libHSfoo.a), or a + single shared object + (e.g. libHSfoo.dll/.so/.dylib). The + restriction to a single shared object is because the package + system is used to tell the compiler when it should make an + inter-shared-object call rather than an intra-shared-object-call + call (inter-shared-object calls require an extra + indirection). - - You need to build an "installed package info" file for - passing to ghc-pkg when installing your - package. The contents of this file are described in . - - - - The Haskell code in a package may be built into one or - more archive libraries - (e.g. libHSfoo.a), or a single DLL on - Windows (e.g. HSfoo.dll). The - restriction to a single DLL on Windows is because the - package system is used to tell the compiler when it should - make an inter-DLL call rather than an intra-DLL call - (inter-DLL calls require an extra - indirection). Building packages as DLLs doesn't - work at the moment; see - for the gory details. - - - Building a static library is done by using the + Building a static library is done by using the ar tool, like so: -ar cqs libHSfoo.a A.o B.o C.o ... +ar cqs libHSfoo-1.0.a A.o B.o C.o ... - where A.o, - B.o and so on are the compiled Haskell - modules, and libHSfoo.a is the library - you wish to create. The syntax may differ slightly on your - system, so check the documentation if you run into - difficulties. - - Versions of the Haskell libraries for use with GHCi - may also be included: GHCi cannot load .a - files directly, instead it will look for an object file + where A.o, + B.o and so on are the compiled Haskell + modules, and libHSfoo.a is the library you + wish to create. The syntax may differ slightly on your system, + so check the documentation if you run into difficulties. + + + Versions of the Haskell libraries for use with GHCi may also + abe included: GHCi cannot load .a files + directly, instead it will look for an object file called HSfoo.o and load that. On some - systems, the ghc-pkg tool can - automatically build the GHCi version of each library, see - . To build these - libraries by hand from the .a archive, it - is possible to use GNU ld as - follows: + systems, the ghc-pkg tool can automatically + build the GHCi version of each library, see + . To build these libraries + by hand from the .a archive, it is possible + to use GNU ld as follows: ld -r ––whole-archive -o HSfoo.o libHSfoo.a (replace - ––whole-archive with - –all_load on MacOS X) - - GHC does not maintain detailed cross-package - dependency information. It does remember which modules in - other packages the current module depends on, but not which - things within those imported things. + ––whole-archive with + –all_load on MacOS X) + + + When building the package as shared object, GHC wraps + out the underlying linker so that the user gets a common + interface to all shared object variants that are supported + by GHC (DLLs, ELF DSOs, and Mac OS dylibs). The shared + object must be named in specific way for two reasons: (1) + the name must contain the GHC compiler version, so that two + library variants don't collide that are compiled by + different versions of GHC and that therefore are most likely + incompatible with respect to calling conventions, (2) it + must be different from the static name otherwise we would + not be able to control the linker as precisely as necessary + to make + the / flags + work, see . + +ghc -shared libHSfoo-1.0-ghcGHCVersion.so A.o B.o C.o + Using GHC's version number in the shared object name + allows different library versions compiled by different GHC + versions to be installed in standard system locations, + e.g. under *nix /usr/lib. To obtain the version number of + GHC invoke ghc --numeric-version and use + its output in place + of GHCVersion. See also + on how object files must + be prepared for shared object linking. + + GHC does not maintain detailed cross-package dependency + information. It does remember which modules in other packages + the current module depends on, but not which things within + those imported things. - To compile a module which is to be part of a new package, + To compile a module which is to be part of a new package, use the -package-name option (). Failure to use the -package-name option when compiling a package will probably result in disaster, but @@ -416,8 +436,8 @@ $ export GHC_PACKAGE_PATH=$HOME/.my-ghc-packages.conf: same as the package name stored in the .hi file. - It is worth noting that on Windows, when each package - is built as a DLL, since a reference to a DLL costs an extra + It is worth noting with shared objects, when each package + is built as a single shared object file, since a reference to a shared object costs an extra indirection, intra-package references are cheaper than inter-package references. Of course, this applies to the main package as well. diff --git a/docs/users_guide/phases.xml b/docs/users_guide/phases.xml index a141352..187bd79 100644 --- a/docs/users_guide/phases.xml +++ b/docs/users_guide/phases.xml @@ -668,10 +668,7 @@ $ cat foo.hspp When generating code, assume that entities imported from a different package will reside in a different shared library or - binary. This currently works on Mac OS X; it works on PowerPC Linux when - using the native code generator. As with , - x86 Linux support is not quite ready yet. Windows is not supported, - and it is a no-op on PowerPC64 Linux. + binary. Note that this option also causes GHC to use shared libraries when linking. @@ -838,10 +835,10 @@ $ cat foo.hspp - Tell the linker to use shared Haskell libraries, if - available (this option is only supported on Mac OS X at the - moment, and also note that your distribution of GHC may - not have been supplied with shared libraries). + This flag switches to shared Haskell libraries for + linking. See on how to + create them. + Note that this option also has an effect on code generation (see above). @@ -849,6 +846,36 @@ $ cat foo.hspp + + + + + Instead of creating an executable, GHC produces a + shared object with this linker flag. Depending on the + operating system target, this might be an ELF DSO, a Windows + DLL, or a Mac OS dylib. GHC hides the operating system + details beneath this uniform flag. + + The flags / control whether the + resulting shared object links statically or dynamically to + Haskell package libraries given as option. Non-Haskell + libraries are linked as gcc would regularly link it on your + system, e.g. on most ELF system the linker uses the dynamic + libraries when found. + + Object files linked into shared objects must be + compiled with , see + + When creating shared objects for Haskell packages, the + shared object must be named properly, so that GHC recognizes + the shared object when linked against this package. See + shared object name mangling. + + + + + + specifying your own main function -- 1.7.10.4