[Info-vax] Shared Objects And DLL Hell

lawrencedo99 at gmail.com lawrencedo99 at gmail.com
Thu Jun 30 02:06:08 EDT 2016


I saw some discussion elsewhere on why Microsoft Windows is prone to “DLL Hell”, and whether Linux had a similar problem.

Linux has shareable libraries (“Dynamic Shared Objects” or DSOs, I believe is the official term) in the form of .so files. I think it avoids DLL hell because of two reasons:
* library versioning to cope with backward-incompatible ABI changes, and
* package management

That is, a shareable library comes from a distro-provided package. Other packages that require that library declare a dependency on that package, which can also specify required versions. So the package manager ensures that installed packages form a consistent dependency graph.

Library versioning is done by sticking a version number after the .so extension. For example, just browsing through my own system, I came across the following:

    root at theon:~ # ls -l /usr/lib/x86_64-linux-gnu/
    ...
    lrwxrwxrwx  1 root root       20 Jun 23 01:28 libapt-inst.so -> libapt-inst.so.2.0.0
    lrwxrwxrwx  1 root root       20 May 23  2015 libapt-inst.so.1.5 -> libapt-inst.so.1.5.0
    -rw-r--r--  1 root root    63360 May 23  2015 libapt-inst.so.1.5.0
    lrwxrwxrwx  1 root root       20 Jun 23 01:28 libapt-inst.so.2.0 -> libapt-inst.so.2.0.0
    -rw-r--r--  1 root root    51280 Jun 23 01:30 libapt-inst.so.2.0.0
    ...

Those files “libapt-inst.so.1.5.0” and “libapt-inst.so.2.0.0” come from two entirely different packages with two different names, not two versions of the same package, which I have installed at the same time:

    root at theon:~ # dpkg-query -S /usr/lib/x86_64-linux-gnu/libapt-inst.so.1.5.0
    libapt-inst1.5:amd64: /usr/lib/x86_64-linux-gnu/libapt-inst.so.1.5.0
    root at theon:~ # dpkg-query -S /usr/lib/x86_64-linux-gnu/libapt-inst.so.2.0.0
    libapt-inst2.0:amd64: /usr/lib/x86_64-linux-gnu/libapt-inst.so.2.0.0

This way, other packages that depend on the older ABI can coexist with those that need the newer one.

Note the symlinks: a bugfix to version 2.0.1 could produce a new library “libapt-inst.so.2.0.1", which would be installed under its own name. The symlink “libapt-inst.so.2.0” can then be updated to point to 2.0.1 instead of 2.0.0, and executables (and other libraries) using the “2.0” name will automatically pick up the new version.

Note also the name with no version suffix:

    root at theon:~ # dpkg-query -S /usr/lib/x86_64-linux-gnu/libapt-inst.so
    libapt-pkg-dev:amd64: /usr/lib/x86_64-linux-gnu/libapt-inst.so

As you can see, this comes from an entirely separate package, with “-dev” in its name.

The versioned libraries come from “run-time” packages, while the unversioned name comes from the corresponding “development” package. The former are all you need to run prebuilt application binaries, while the latter is what you need to build those applications. The linker follows the symlink, and automatically includes the versioned library name in the executable it generates.

Windows has nothing like this. Which is why it has so much trouble with library version conflicts.



More information about the Info-vax mailing list