In which I set up Android Build Tools to run on a 64-bit System without Multiarch

The problem

I was creating a build server for an Android project on a remote web host run by Webfaction, but I was running into a problem when running the ant scripts. I had installed the Android SDK in my home directory according to these instructions, but running ant clean debug threw this error:

I checked, and /home/stevehb/bin/android-sdk-linux/build-tools/20.0.0/aapt existed. I couldn’t see a reason that ant couldn’t find it, so I eventually tried to run it myself.

That clearly seems to be the problem. I looked around some more and found that /lib/ was empty while /lib64/ had all the usual shared libraries. I was thinking this was going to be a problem because I don’t have root access to these parts of the system. Basically, it looks like Google is shipping 32-bit binaries in its Android toolset, and I’m on a 64-bit-only system.

Google eventually led me to someone with a similar problem, only trying to run Steam on the servers instead. Fortunately, there’s a solution. Unfortunately, it’s convoluted and tedious, and not easily scripted as far as I can tell.

The beginnings of a solution

Before we get to the tedious part, there’s some setup needed. To fix this, you’ll need to make your own directory for 32-bit libs on the server. For me this was /home/stevehb/lib/. I also set up a directory for the RPMs that we’ll need to download.

Now modify the LD_LIBRARY_PATH environment variable to point to your new 32-bit lib directory. You can put this into ~/.bash_profile:

Don’t forget to run source ~/.bash_profile to update your current session.

Also download the patchelf tool. You can build it yourself from that source, but the post that Google found has a binary linked here, and I have the same binary hosted here. It’s 64-bit, statically linked, so should work on pretty much any system.

Next, find the RPM repo for your distro. Webfaction runs Centos 6, so for me this was my package list.

And finally, open up this RPM finder website. This is where you’ll search for the missing libraries to find out which RPMs you need to download.

A rigmarole: the extraction procedure

Search for the missing file, ld-linux.so.2, on the RPM finder site. Specifying your system (eg, “centos”) will narrow the results. Choose the 32-bit RPM that matches the distro version, and copy the name. In this case, it’s glibc-2.12-1.132.el6.i686.rpm

Now search for the name on your distro’s package list. This will give you a URL to download the file. Download the RPM to the RPMs directory on the server.

Next, extract the files from the RPM, and copy the libraries into your 32-bit lib directory. You can then remove all the files that got extracted.

On interpreters and rpaths

There are 2 stages for each of the 32-bit binary files we’re trying to fix. First, we need to set the interpreter and rpath. That will tell the binary where to look for the 32-bit libraries that it’s missing. Then we need to repeatedly run the binary to find out which other 32-bit libraries it’s still lacking. For each of those files, we find the RPM, extract it, and copy the files to our own lib directory. The first file we’re missing is ld-linux.so.2. It’s the interpreter, so we need to get that before working on the other missing libraries.

We’ll need to run the following commands for each of the 32-binaries that we need to use in the Android SDK. We’re using patchelf to relink them by setting the interpreter, and the default search path (the rpath). Be sure to use the absolute path name for interpreter and rpath locations.

Now that aapt knows where to look for libs, run it again.

Progress! Looks like it found ld-linux.so.2, and now it’s missing libz.so.1. From here, we just repeat the extraction procedure (RPM finder, download RPM, extract, and copy to ~/lib) for any other files that aapk reports as missing.

Beyond aapk

After I got aapk working normally, I tried running the initial ant clean debug command again. Luckily, I didn’t have to go through the whole RPM rigmarole again. zipalign was having difficulty, but all it needed was a new interpreter and rpath. After that, the ant command worked. All in all, here are the results:

Needs new interpreter and rpath

  • aapk
  • zipalign

RPMs to download, extract, and copy

  • glibc-2.12-1.132.el6.i686.rpm
  • zlib-1.2.3-29.el6.i686.rpm
  • libstdc++-4.4.7-4.el6.i686.rpm
  • libgcc-4.4.7-4.el6.i686.rpm

Final note about updating

When updating the Android SDKs, some of these files that you’re patched could be replaced during the update. You probably won’t need extra libraries from the RPMs, so try just re-setting the interpreter and rpaths for any binaries first. That could make the fix a lot faster.

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *