It has come to my attention that the maintainer of the Debian Mozilla packages (Mike Hommey) is using patches that significantly alter the XULRunner linking strategy (first discussed here).These patches cause various Mozilla libraries to be soversioned and installed in the library path (/usr/lib). Although I have emailed Mr. Hommey privately on a number of occasions, I have not received a reply, and the linking strategy that he has implemented is poorly thought out and will lead to instability and frustration.
On Linux systems, traditional shared libraries are installed into the system path (typically /usr/lib). In addition, there is a mechanism to support versioning, such that multiple versions of a library can be installed at the same time. This mechanism records information about the symbols provided by the library: incompatible changes are marked by a revision of the library’s major version number, backwards-compatible additions are marked by a change in the library’s minor version number, and minor bugfixes are marked by a revision of the micro (or release) version number. When an application is linked against a shared library, the version numbers are stored in the library and the dynamic linker ensures that when the application is loaded a library that is compatible is loaded.
Mozilla is not just ABI
For libraries where the provided functionality matches the exported functions, this simple solution works well. But the Mozilla libraries are an entirely different situation: XPCOM libraries export a small set of frozen APIs, but the stability of these initialization and accessor APIs has little to do with the stability of the actual functionality provided by gecko (XULRunner). Almost all XPCOM functionality is exposed through interfaces, which are versioned using UUIDs. As functionality is completed, these interfaces and the contractIDs that allow access to components are frozen, which guarantees that they will not change in future releases. Thus the functionality exposed by Mozilla is a set of frozen functionality exposed through interfaces, and a much larger set of nonfrozen functionality.
XPCOM also has the ability to load an extensible binary XPCOM components: these components, if carefully written, can work with multiple versions of XPCOM and the various applications written on top of XPCOM. It is important that XPCOM components can continue to be compiled which work with multiple applications and versions. It is also important that when these component are loaded they use the XPCOM symbols from the currently running version of XPCOM library; if these components were to load an alternate XPCOM library, they would quickly crash or at least fail in unexpected ways.
The Proven Solution
In order to allow multiple versions of XPCOM to coexist correctly on a machine, Mozilla has developed a linking strategy which allows applications to find a compatible version of XPCOM (XULRunner) and load it at runtime. This is called the standalone XPCOM glue. The standalone glue linking strategy has the following characteristics:
- Multiple versions of XULRunner are installed in separate directories.
- System XULRunners are typically installed in /usr/lib/xulrunner-126.96.36.199, /usr/lib/xulrunner-188.8.131.52, etc. Each version is registered in a *.conf file in /etc/gre.d.
- XULRunner can also be installed in a per-user location, typically ~/.lib/xulrunner-184.108.40.206 etc, and is registered in a configuration file within ~/.gre.d.
- An application which wants to use XPCOM APIs does not link directly against libxpcom.so (which would not be found, because it is not in the default library search path). Instead, it links against the standalone glue (libxpcomglue.a), a static library without mozilla shared library dependencies. During startup, the application calls the function GRE_GetGREPathWithProperties to locate a compatible XULRunner. It then calls XPCOMGlueStartup(), which dynamically loads the correct XULRunner libraries.
A great deal of effort was put into developing this linking strategy so that it actually works properly; and it does work properly on all three of the major platforms that Mozilla supports (Windows, Mac OS X, and Linux). It allows for relocatable installs of both the XULRunner platform and the applications that depend on the platform, which is an important part of Mozilla’s user-centric software model. XULRunner packages which use this linking model have been prepared on SuSE and other distros.
Debian Going Their Own Way
Unfortunately, the Debian pacakagers have decided to go their own way and try to create XPCOM libraries which can be versioned and installed in the system library path. This decision is ill-conceived: it means that XPCOM components built for other Linux systems are almost guaranteed not to work correctly on Debian systems: they will in many cases load the wrong XPCOM library and fail spectacularly. It also means that it will be impossible to compile XPCOM components on Debian systems that will work with multiple versions of an application, or on any other Linux system.
I am sure that the Debian team believes that this change in linking strategy is better and correct and that they are not acting maliciously; but the fact remains that they have not proposed or discussed their changes with me (as both build-sytem and embedding API owner in Mozilla), nor have they responded to my mails. I don’t think I have any choice but to publicly point out the significant flaws in their linking strategy and encourage Debian via peer pressure to rethink their poorly thought out decision.