Update: Bug 253742 is very close to being fixed, so the workarounds in this post will no longer be needed. Thanks to the Mozilla developers for making the platform even better.
I wanted to have a single extension package (XPI), which included the XPCOM components for all the platforms. When the extension is installed, it should detect the user platform and load only the appropriate components.
The first thing I noticed is that the extension manager mechanism doesn’t allow conditional installations (install different components depending on user’s platform).
Next, I tried the following reasoning: package both .dll and .so files with the extension. Firefox on Windows will load only the .dll files while ignoring the .so files, and on Linux only the .so files, while ignoring the .dll files. It was only logical to me that the Windows version of Firefox will not try to load the .so files.
It didn’t work. Windows Firefox did try to load the .so file and popped up and ugly message box saying something about wrong file format. Looking through Mozilla source code, I saw that there is a list of all the dynamic libraries extensions (.dll, .so etc.) and Mozilla will try to load all the file types on all the platforms.
After posting a question on the mozillazine.org forums, I got an answer saying that I should provide several different packages for the different platforms. I wasn’t ready to go that way. Managing several packages, when all that is different between them is a single file seemed unreasonable.
So I came up with a work-around. I had only Windows and Linux versions, but the technique can be extended further to support more platforms. Here it is:
- Package the Windows version of the component as
- Package the Linux version of the component as
- Windows will load the .dll file while ignoring the .dll.linux file (because its extension is not a valid dynamic library extension). Nothing else should be done here.
- On Linux – the first time the extension is loaded, it will try to load
MyComponent.dllfile and fail (because the file is a Windows DLL). It will fail gracefully, without popping up any message boxes.
- During the startup of my extension I check whether the user platform is Linux and if
- If so, this means that this is the first run. The script moves (renames)
MyComponent.dll, removes the components registry files,
xpti.dat, so they are rebuilt the next time Firefox is started
and inform the user that an additional restart is needed.
- When the browser is restarted, the
MyComponent.dllis loaded successfully (because it is now a valid .so file) and the registry files are rebuilt to reflect its contents.
- The extension is now fully functional.
One little question needs to be answered – why do I rename
MyComponent.dll and not to something more Linux-like as
The answer is – uninstall. If I created a new file named
MyComponent.so, when my extension got uninstalled the file wouldn’t have been deleted, because it was never installed. Moving
MyComponent.dll leaves all the files with exactly the same names, so when uninstall comes, they are removed.