back
7 comments
Debian, interestingly, has recently had a push exactly in the opposite direction, mainly for the "fixing bugs once fixes them everywhere" reason. Over the years a lot of packages have for various reasons statically linked in private copies of a library (sometimes on purpose, sometimes just because upstream did so), which causes the Debian security team no end of headaches, because they have to track down all of these and fix them if there's a security-relevant bug. Since Debian Stable tries not to push too many updates unless absolutely necessary, it also screws things up there, because instead of updating one package for one library's bug, they have to update all N packages that made private copies of the library, so sysadmins expecting rare, infrequent security fixes instead get presented with a big pile of packages that want to be updated.
This idea scares me a bit. Mostly for the rare awful occasions when people either rely on buggy behaviour, or patch around it on the caller side in some unexpected way.

I can see it making perfect sense for security updates, but if you have it then you have it for all library updates - security or not.

Yeah, though I think it's mitigated a little bit with a managed-as-a-whole system like Debian, at least if there's communication. Sometimes things break, but sometimes things do actually work, and the maintainers will talk to each other to coordinate updates, inform each other when a change is likely to break other things, etc.
Like any technical measure, dynamic linking comes in good and bad flavors.

I generally like the idea of proper software libraries, shared code, and the one-place-to-fix-them-all mentality. For many things, that's the way it fits. However, what I don't like is the tendency to turn nearly everything into a library, even within a single program. For example, check out the directory /usr/lib/firefox-3; on my setup there are 15 different shared objects—all used by the one single executable. The same goes for a program that's merely a driver for a set of custom shared objects. And for frameworks such as Gnome: I'm pretty sure gedit* doesn't have to depend on 57 shared objects like mine does.

Dynamic linkage is good for linking through solid APIs. Like libc. Or OpenGL. Maybe some high-level compositions of Gnome or other desktop stuff. Generally, such stuff that rarely changes; stuff where the gestation period between version N and N+1 is years. However, dynamic linkage is bad for merely splitting code into manageable chunks. For that, just use static libraries for that and link them all together.

gedit is pretty complex.

    libgtksourceview-2.0.so.0
    libgconf-2.so.4
    liblaunchpad-integration.so.1
    libgtk-x11-2.0.so.0
    libgdk-x11-2.0.so.0
    libatk-1.0.so.0
    libgio-2.0.so.0
    libgdk_pixbuf-2.0.so.0
    libcairo.so.2
    libpango-1.0.so.0
    libgobject-2.0.so.0
    libgmodule-2.0.so.0
    libgthread-2.0.so.0
    libglib-2.0.so.0
    libX11.so.6
    libSM.so.6
    libm.so.6
    libpthread.so.0
    libc.so.6
    libICE.so.6
    libpangocairo-1.0.so.0
    libxml2.so.2
    libORBit-2.so.0
    libdbus-glib-1.so.2
    libdbus-1.so.3
    librt.so.1
    libXcomposite.so.1
    libXdamage.so.1
    libXfixes.so.3
    libpangoft2-1.0.so.0
    libfreetype.so.6
    libfontconfig.so.1
    libXext.so.6
    libXrender.so.1
    libXinerama.so.1
    libXi.so.6
    libXrandr.so.2
    libXcursor.so.1
    libdl.so.2
    libpcre.so.3
    libresolv.so.2
    libz.so.1
    libselinux.so.1
    libpixman-1.so.0
    libdirectfb-1.2.so.0
    libfusion-1.2.so.0
    libdirect-1.2.so.0
    libpng12.so.0
    libxcb-render-util.so.0
    libxcb-render.so.0
    libxcb.so.1
    libuuid.so.1
    libexpat.so.1
    libXau.so.6
    libXdmcp.so.6
How would you improve?

Outside the duplication of XCB and the libX11 based libraries, it's hard for me to see much that isn't at least justifiable.

I understand why the X extension libraries are all broken up. But, in the modern world, it seems likely the same set get loaded time and time again. It would be "simpler" if they were all in one library.

gobject/glib/gmodule and friends could get sewn up. Same as gdk/gtk/atk.

(Though, why the hell is directfb in there?)

Here's a rough logical grouping, based on whatever I might be interested as the "end-developer"—i.e. the guy who just wants to use these libraries and not be concerned too much about how they're internally stacked together.

Note that I simply recognize many of these libraries but I'm definitely not an expert on each one, so many of them might belong to some other logical group. YMMV.

First, GUI stuff: if I want to make graphical UIs in style of GTK, then I probably want all of these and more.

  libgtkgui.so:
  - libatk-1.0.so.0
  - libgdk-x11-2.0.so.0
  - libgdk_pixbuf-2.0.so.0
  - libgtk-x11-2.0.so.0
  - libgtksourceview-2.0.so.0
  - libpng12.so.0
Font rendering: if I want to render text I'll probably want all of these anyway, preferably facaded over one high-level API.

  libfonts.so:
  - libcairo.so.2
  - libfontconfig.so.1
  - libfreetype.so.6
  - libpango-1.0.so.0
  - libpangocairo-1.0.so.0
  - libpangoft2-1.0.so.0
Basic G-stuff: if I want to use the low-level glib etc. stuff without GTK and other gui stuff, I probably want something like this.

  libgbase.so:
  - libORBit-2.so.0
  - libgconf-2.so.4
  - libgio-2.0.so.0
  - libglib-2.0.so.0
  - libgmodule-2.0.so.0
  - libgobject-2.0.so.0
  - libgthread-2.0.so.0
  - libuuid.so.1
If I want to do X development, I probably can't avoid dragging most of these with me already, and I'm not particularly interested in which libraries might I possibly need. All I want is X.

  libx.so:
  - libICE.so.6
  - libSM.so.6
  - libX11.so.6
  - libXau.so.6
  - libXcomposite.so.1
  - libXcursor.so.1
  - libXdamage.so.1
  - libXdmcp.so.6
  - libXext.so.6
  - libXfixes.so.3
  - libXi.so.6
  - libXinerama.so.1
  - libXrandr.so.2
  - libXrender.so.1
  - libdirect-1.2.so.0
  - libdirectfb-1.2.so.0
  - libfusion-1.2.so.0
  - libpixman-1.so.0
  - libxcb-render-util.so.0
  - libxcb-render.so.0
  - libxcb.so.1
The very base posix environment: I'll have to link with many of these already so it would be handy to just umbrella them into one base lib. I would also not have to remember if I need libm or libpthreads separately as is the case with slightly different Unix environments these days.

  libposixish.so:
  - libc.so.6
  - libdl.so.2
  - libm.so.6
  - libpcre.so.3
  - libpthread.so.0
  - libresolv.so.2
  - librt.so.1
  - libselinux.so.1
  - libz.so.1
These are surprisingly non-dependent on other libraries so these could be bundled into one small library. I think.

  libxml.so:
  - libexpat.so.1
  - libxml2.so.2
Not sure if this would be part of my libgtkgui.so or libgbase.so or libposixish.so, or if they would belong to something called libgnome.so, so they're left here as separate libraries.

  libdbus-1.so.3
  libdbus-glib-1.so.2
  liblaunchpad-integration.so.1
I'm pretty sure there are niche cases where you would really want to reuse a particular sub-library only, but you could just depend on the big blob anyway. You see, the common parts of the big blob are in use and in memory already as the whole thing is mapped from disk to memory. But if nobody uses a particular sub-library it won't be loaded to actual memory either until someone touches its address space.

So, instead of linking with the sublibrary directly, you could just start using it within the big library, and the same process of loading from disk to memory will then automatically happen. Conversely, even if you have a gigantic 100MB libgnome you might just generally end up having only a part of it in memory.

The VMS operating system has had dynamic linking for thirty years or so.

A simple version identifier match scheme allows for the requirement of at least a specified version or newer of the library (not running against an older version), or flagging that an incompatible API change has been made (not running against an incompatible version).

The dynamic linking mechanism then checks this pair of identifier values that is associated with each library, and allows (or disallows) activation of the calling application.

There's also a mechanism to redirect the activation, which allows you to maintain a private version of the library. And yes, there are security implications for some cases of this redirection.