Alex headshot

AlBlue’s Blog

Macs, Modularity and More

Adventures in Multi-Architecture Eclipse

2011, eclipse, rant

I've been working on a multi-architecture single build for Eclipse, as described previously, and have now got it to a state where I can generate a build for multiple architectures into a single install. Unfortunately, it's not easy to script with Tycho (yet) but it can be done.

The problem is largely with P2. Although the plugin soup can handle having plugins installed for both its platform and others simultaneously, P2 needs to be told (through the use of a profile) which subset it is to look at. Instead of doing something sensible (say, assuming that the current set of installed plugins represents the 'starting point' and going from there), P2 insists that the profile be built up by a series of installation requests.

The problem is this profile contains architecture-specific installation. Even if you install the same RCP base product, the profiles are different as they reference different fragments (so, on an x86 build you have SWT-x86, and on an x86_64 build you have SWT-x86-64). Due to this three character difference, you have to build the product twice.

The first approach – use a shared bundle pool – doesn't work. That's because P2 checks to see if a bundle has already been installed, and if so, skips it. This works fine for bundles without architecture-specific fragments, but fails for those with. Run P2 on a shared install for x86 and x86-64, and when the second install happens, it says “Hey! SWT is already present; nothing to do”. Of course, this misses the fact that SWT needs the SWT-x86-64 fragment in order to work and so you end up with a failed product.

The second problem is the configuration folder. Although this is 99% platform agnostic, the simpleconfigurator has a list-of-bundles to install upon startup. This too contains the architecture-specific fragments, so although it is almost identical, it differs in a few key places.

Fortunately, all is not lost. We can fix this by doing three things:

  1. Have each architecture have its own profile name
  2. Have each architecture have its own configuration directory
  3. Rename the executables per platform (and corresponding ini files)

The first is relatively easy; in the P2 director, pass a different profile name. Unfortunately, Tycho doesn't currently let you have a different profile name per architecture so you either have to use two projects or a hacked version in order to achieve this goal.

The second is more challenging. There's no way of telling the director what the configuration directory should be at build time, although you can specify this at run time. The trick is to rename the configuration directory to something architecture-specific (say, configuration.x86-64) and then write a pointer to that from the ini file for the launcher; e.g. -config configuration.x86-64. That way, running Eclipse.x86-64.exe will load Eclipse.x86-64.ini, which points to configuration.x86-64.

This does mean that an installation of a plugin for one architecture won't make it visible in the other architecture (they share different configuration and profile directories) but at least both can be launched from a single image. A post-process cleanup script can be run on a per-installation basis to remove unnecessary products if desired.

Being able to serve a single platform from a single build is an important one in minimising download and maintenance costs across an organisation or disk usage across the internet as a whole. Adding launchers for other architectures doesn't add much to the installer size; though whether it makes sense to combine different platforms (Windows, Mac, Linux) may be up to the use cases and policies that require them. And whilst it's possible to merge the executables for those that support fat binaries, this isn't possible on all platforms.

However, there's really no reason why there isn't a single build for Windows (all platforms), Linux (all platforms) and Mac (all platforms). It shouldn't be necessary to have to download everything again just to get a slightly different fragment, and maybe this approach will be a way of allowing a transition to occur to a more sensible build strategy.