[Mono-devel-list] Proposal: Library Loading

Jonathan Pryor jonpryor at vt.edu
Tue Apr 13 20:52:06 EDT 2004


This came up on #mono today in the context of Fedora and package
management, so I figured I'd document the current idea for discussion
and possible future implementation [1].

The Problem:

DllImport doesn't allow developers to specify which library version to
load at runtime.  Thus, with code such as:

	[DllImport ("foo")]
	private static extern void foo ();

Mono will attempt to load "libfoo.so" at runtime.

There are three problems with this:

1.  What happens if there are multiple major versions of libfoo.so
    installed: libfoo.so.1 and libfoo.so.2?  Which gets loaded?  At
    present, whichever libfoo-devel package was installed, which may be
    ABI-incompatible with what the assembly was written against.  Oops.

2.  Ignoring (1), the user needs to have N MB of -devel packages
    installed in order for Mono to find the .so file (as the .so file is
    usually only present in the -devel packages).  N can be very large;
    previously, I've heard of N > 50 MB.  Users will find this to be
    unacceptable.

3.  To avoid (2), the user can edit $prefix/mono/config, an XML file
    which "maps" the DllImport library to the actual library to load. 
    While this works, it is inelegant (the user has to edit XML, which
    may scare some users), and is not extensible (what should happen
    when a new library/assembly/RPM is installed?).


The Proposed Solution:

Scrap $prefix/mono/config, and replace it with a $prefix/mono/config.d
directory.  This directory would contain one file per DllImport "base"
name, where a base name is the library name without the "lib" prefix and
any suffix (".so", ".dll", .etc).

The syntax of the XML file could be:

	<library>
		<dll import="DllImport Attribute Value" 
			target="actual library to load"
			version="version .NET assembly targets"/>
	</library>

For example, the C library would have an entry in
$prefix/mono/config.d/c.xml, which the contents:

	<library>
		<dll import="libc" 
			target="libc.so"
			version="6" />
	</library>

The version attribute is present to solve problem (1), and would contain
the major and optional minor version number of the library to load. 
Mono's library loading logic would thus need to search for the
${target}.${version} library in the standard locations (LD_LIBRARY_PATH,
/etc/ld.so.conf, /usr/lib, /lib), with intelligent fallback handling
(e.g. if @version is 1.2, and ${target}.1.2 isn't present, but
${target}.1 is, then ${target}.1 should be loaded).

Benefits:

The "one file per base library name" ensures that only one package (RPM,
etc.) will attempt to "own" a particular library, so we don't have
multiple packages attempting to "own" the GTK+ libraries.

The version number attribute benefits were mentioned above.

Future packages can install files into $prefix/mono/config.d as part of
their install, ensuring that any native libraries they require will be
found by Mono, simplifying package maintenance.

The one potentially troubling part is the duplication between the file
name and the /library/dll/@import attribute value.

Thoughts?

 - Jon

[1] Alas, I'm not implementing this.  I plead lack of time. :-(





More information about the Mono-devel-list mailing list