On the dynamic loading of drivers

With the recent addition of the dynamic loading of the X11 driver,
I can see a trend that I think will lead to much code duplication and
uglyfication as well as a more difficult code maintenance.

As far as I understand, dynamic loading of the drivers serves two
main purposes:

  • avoid linking libSDL with too many extra libraries that may not even
    be installed
  • make it straightforward to activate support for one of these
    libraries once they are installed

Currently SDL has the following problems:

  • the version of libX11 is hardcoded to 6; on Solaris, the Openwin
    libX11 is libX11.so.4
  • if more than one version of the dynamically opened libraries
    (libasound, libesd, libartsc) is installed on the build system, only
    one version will be used by libSDL and which one will be chosen is
    undetermined (but fixed at build time)

These are minor details. A more important problem is dependency
tracking. Since the library keeps no link with the library that was on
the build system, there is no easy way to know which version of say,
libartsc is needed for libSDL to work. Linux distributions which use the
linker information in each ELF object to track dependencies will miss
that one.

Now one may argue that if it causes so many trouble to Linux
distributions then they just need not to activate the feature. But
dynamic loading of drivers is a very useful feature, and I just think
there is a way to do it better.

The solution I propose is to make the whole driver a separate shared
library that simply exports a unique symbol that is an AudioBootStrap
or VideoBootStrap pointer. The amount of code needed to support that
feature is quite small: it’s just a matter of browsing a given directory
(eg. /usr/lib/SDL/1.2/) and dynamically loading what is in there. If the
library required by a given plugin is not here, it will simply fail to
load.

Before:

±---------------------+ dynamically ±----------+
| libSDL | ALSA driver |— loads --> | libasound |
±---------------------+ on demand ±----------+

My proposal:

±-------+ dynamically ±------------+ ±----------+
| libSDL |— loads -->| ALSA driver |-- links -> | libasound |
±-------+ on demand ±------------+ with ±----------+

The amount of code that needs to be changed in each plugin for this
to work is exactly zero lines. Admittedly, there is some work to do on
the build system, but nothing really hardcore, and it gets rid of the
ugliness that currently sits in configure.in.

I have already started working on this for the Debian version of
libSDL. I want to provide a way for our users to selectively install
ALSA, esd or aRts support for SDL, and currently we have no other choice
but to provide 4 different packages containing full versions of libSDL
with the given plugin compiled in or not.

Also, I may have sounded quite Linux centric here, but my proposal
works of course on every Unix platform and BeOS. It will probably not
work on Win32 because of the way DLLs work, but that platform does not
really need it.

I will send clean patches when this is done, but I just wanted to
know the general opinion about the proposal. FWIW, it is exactly how the
Allegro library works. Let me know what you think.

Regards,–
Sam.

I’m not opposed to this, as a build option. A long time ago we decided
to keep a single library without lots of little driver files hanging around.
I still think this is the right decision for game redistribution, but for
distros it may make sense to use a subobject model.

Patches are welcome, as long as the option is there to build SDL either way.> With the recent addition of the dynamic loading of the X11 driver,

I can see a trend that I think will lead to much code duplication and
uglyfication as well as a more difficult code maintenance.

As far as I understand, dynamic loading of the drivers serves two
main purposes:

  • avoid linking libSDL with too many extra libraries that may not even
    be installed
  • make it straightforward to activate support for one of these
    libraries once they are installed

Currently SDL has the following problems:

  • the version of libX11 is hardcoded to 6; on Solaris, the Openwin
    libX11 is libX11.so.4
  • if more than one version of the dynamically opened libraries
    (libasound, libesd, libartsc) is installed on the build system, only
    one version will be used by libSDL and which one will be chosen is
    undetermined (but fixed at build time)

These are minor details. A more important problem is dependency
tracking. Since the library keeps no link with the library that was on
the build system, there is no easy way to know which version of say,
libartsc is needed for libSDL to work. Linux distributions which use the
linker information in each ELF object to track dependencies will miss
that one.

Now one may argue that if it causes so many trouble to Linux
distributions then they just need not to activate the feature. But
dynamic loading of drivers is a very useful feature, and I just think
there is a way to do it better.

The solution I propose is to make the whole driver a separate shared
library that simply exports a unique symbol that is an AudioBootStrap
or VideoBootStrap pointer. The amount of code needed to support that
feature is quite small: it’s just a matter of browsing a given directory
(eg. /usr/lib/SDL/1.2/) and dynamically loading what is in there. If the
library required by a given plugin is not here, it will simply fail to
load.

Before:

±---------------------+ dynamically ±----------+
| libSDL | ALSA driver |— loads --> | libasound |
±---------------------+ on demand ±----------+

My proposal:

±-------+ dynamically ±------------+ ±----------+
| libSDL |— loads -->| ALSA driver |-- links -> | libasound |
±-------+ on demand ±------------+ with ±----------+

The amount of code that needs to be changed in each plugin for this
to work is exactly zero lines. Admittedly, there is some work to do on
the build system, but nothing really hardcore, and it gets rid of the
ugliness that currently sits in configure.in.

I have already started working on this for the Debian version of
libSDL. I want to provide a way for our users to selectively install
ALSA, esd or aRts support for SDL, and currently we have no other choice
but to provide 4 different packages containing full versions of libSDL
with the given plugin compiled in or not.

Also, I may have sounded quite Linux centric here, but my proposal
works of course on every Unix platform and BeOS. It will probably not
work on Win32 because of the way DLLs work, but that platform does not
really need it.

I will send clean patches when this is done, but I just wanted to
know the general opinion about the proposal. FWIW, it is exactly how the
Allegro library works. Let me know what you think.

Regards,

Sam.


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Patches are welcome, as long as the option is there to build SDL either way.

For what it’s worth, I would frown on doing this, since it makes things
much more complex…moving as we are towards dynamically loading
dependencies in an otherwise monolithic library solves the distro
packaging problem and keeps it simple for packaging something that works
everywhere as a single file (which helps me, if no one else).

Granted, there’s still some issues we’re cleaning out, especially in the
new dynamic X11 code, but they’ll be solved soon enough.

–ryan.