[HOpenGL] Compiling HOpenGL under recent versions of GHC

Glynn Clements glynn.clements at virgin.net
Fri May 21 16:53:25 EDT 2004


Sven Panne wrote:

> > So, if I understand the situation correctly: reversing the library
> > order in package.conf may work for ghci, and might not do any further
> > harm under Linux at all, but generally is not a good solution because
> > it breaks compilation on some other platforms. Therefore it would be
> > better to integrate the dependencies between the libararies properly
> > into the .so files.
> 
> Exactly. The GNU ld pages are quite clear about the order of archives, see
> the description of the -l option:
> 
>     http://sources.redhat.com/binutils/docs-2.15/ld/Options.html
> 
>     "The linker will search an archive only once, at the location where it
>     is specified on the command line. If the archive defines a symbol which
>     was undefined in some object which appeared before the archive on the
>     command line, the linker will include the appropriate file(s) from the
>     archive. However, an undefined symbol in an object appearing later on the
>     command line will not cause the linker to search the archive again.
> 
>     See the -( option for a way to force the linker to search archives multiple
>     times."
> 
> After reading this, it is a miracle for me why the order doesn't seem to matter
> on my SuSE Linux... %-]

Regarding the above citation, note that an "archive" is a *static*
library (i.e. a ".a" file). The ordering doesn't matter for linking
dynamic libraries.

However, if any of the shared libraries which are listed in
package.conf are missing dependency information, then the ordering
will matter for dynamic loading (e.g. for ghci). And the ordering
needs to be the reverse of that for linking static libraries.

When linking static libraries, the consumer must be listed first, so
that when the linker gets to the provider it knows which objects are
required. An archive (".a") file is just a container of object (".o")
files (conceptually similar to a ".zip" file). The linker effectively
extracts only those object files which are known to be required, and
links them in as it would any object files which were listed on the
command line.

When loading dynamic libraries at run time with dlopen() (or
equivalent), the provider must be be loaded before the consumer
(unless the consumer lists the provider as one of its dependencies),
otherwise loading the consumer may[*] fail due to an undefined symbol.

[*] Depending upon the OS and the flags passed to dlopen(). On Linux,
it depends upon whether dlopen() was called with RTLD_LAZY or
RTLD_NOW. Using RTLD_LAZY allows for undefined symbols; however, if
they don't actually get provided, calling a function which requires
them will result in sudden termination of the program. OTOH, using
RTLD_NOW would result in dlopen() failing (returning NULL), which is
easier to handle.

Whereas "ld" expects some symbols to be undefined at intermediate
stages of the linking process, and only complains if any symbols
remain undefined at the end, a call to dlopen() may require that no
symbols remain undefined upon its return. The fact that an undefined
symbol could be provided by a subsequent dlopen() doesn't help.

If the library lists in package.conf are being used for both purposes
(i.e. ld and dlopen()), they should probably processed in opposing
directions for dlopen() vs ld.

-- 
Glynn Clements <glynn.clements at virgin.net>


More information about the HOpenGL mailing list