0

I would like to compile Android Apps with SDK 23.0.3 as a user on CentOS. Unfortunately, everytime build-tools/23.0.3/aapt is run, it returns

bash: build-tools/23.0.3/aapt: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory

The problem seems to be that 32 bit libraries need to be installed. If I have sudo rights (on Ubuntu), I can run sudo apt install libc6-i386 lib32stdc++6 lib32gcc1 (like described in CentOS 64 bit bad ELF interpreter), but unfortunately, I do not have sudo on the machine where I would like to compile.

I assumed that I could get the used libraries (like described in https://www.cs.virginia.edu/~dww4s/articles/ld_linux.html) and then replace the used libraries by setting LD_LIBRARY_PATH (like described in http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html). I extracted the libraries by

   ldd ../androidsdk/build-tools/23.0.3/aapt | \
     grep "i386" | awk '{print $3}' | \
     while read file
       do cp $file .
     done

and copied them to /home/test. Then I ran export LD_LIBRARY_PATH=/home/test, but then aapt returns the same error.

Another thing I tried was getting and extracting the libraries (on Ubuntu):

apt-get download libc6-i386 lib32stdc++6 lib32gcc1 
for file in *.deb
   do dpkg -x $file .
done

And aftwards setting the LD_LIBARY_PATH to /home/test/lib:/home/test/lib32, which also did not work.

This could be reproduced by a docker container: running docker run -it ubuntu bash and then

apt update && apt install git unzip wget openjdk-8-jdk
cd home/
wget https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip
unzip sdk-tools-linux-4333796.zip
cd tools/
yes | bin/sdkmanager --install "build-tools;23.0.3"
cd ..

For setup. Then, build-tools/23.0.3/aaptreturns

bash: build-tools/23.0.3/aapt: No such file or directory

which is the same problem as in the CentOS (Can not run android/sdk/build-tools/23.0.2/aapt): A 32 bit library is missing.

Can someone tell me what would be the correct way to add the libraries?

EDIT Since the interpreter, normally /lib/ld-linux.so.2 starts interpreting files, it needs to be replaced. If I manually extract all .so-files like described above, put them in lib/ and run

LD_LIBRARY_PATH=$(pwd)/libs libs/ld-linux.so.2 build-tools/23.0.3/aapt

the aapt-command is executed correctly. Unfortunately, this is not enough for building:

LD_LIBRARY_PATH=/nfs/user/do820mize/workspaces/dissworkspace/androidsdk/libs /nfs/user/do820mize/workspaces/dissworkspace/androidsdk/libs/ld-linux.so.2 ./gradlew --init-script ../init.gradle assemble

returns the ELF-error again, since the gradle-wrapper (and Java and so on) are 64 bit binaries.

David Georg Reichelt
  • 963
  • 1
  • 15
  • 36
  • 1
    Ask someone with root rights to install the libraries. – Henry Jan 29 '19 at 13:40
  • Unfortunately, this is not possible for organizational reasons. I need to make this runnable by environment variables, placing the libraries in the correct folder etc. – David Georg Reichelt Jan 29 '19 at 13:48
  • You will probably still need root permissions to place the libraries in the correct folders. – m0skit0 Jan 29 '19 at 13:56
  • Install your own build environment without weird "organizational reasons". – Erki Aring Jan 29 '19 at 14:03
  • The current environment is a cluster which I need to use for parallel and fast builds and tests. Therefore, I need to somehow run this on the cluster. Shouldn't it be possible to load the libraries by `LD_LIBRARY_PATH` or `LD_PRELOAD`? – David Georg Reichelt Jan 29 '19 at 14:07
  • Is using docker an option? You could do the build inside a container. – Henry Jan 29 '19 at 14:09
  • Unfortunately not. It is a slurm-cluster where I only am allowed to run jobs as user. I could only use docker for reproducing the problem locally (since I locally installed the libraries already). – David Georg Reichelt Jan 29 '19 at 14:13

2 Answers2

0

glibc.i686 is available from the base repository:

$ yum whatprovides ld-linux.so.2

glibc-2.17-260.el7.i686 : The GNU libc libraries
Repo        : base
Matched from:
Provides    : ld-linux.so.2

in case it should not be possible to have basic dependencies provided, that cluster is useless. of course it would need to be installed on all nodes; the chances that it would break something are rather slim, while having the same version number for the x86_64 version of the glibc library.

Martin Zeitler
  • 1
  • 19
  • 155
  • 216
0

The problem is, that the header of the elf file (e.g. aapt) contains a link to the interpreter (e.g. /lib/ld-linux.2.so). This link needs to be replaced for execution, but only for the 32 bit elf-binaries. Gradle and Java still need to be executed with their regular 64 bit Interpreter. Since the processes that are called (e.g. aapt) are sub processes, calling another interpreter directly is not possible.

One possible solution is using patchelf (https://nixos.org/patchelf.html). First, it needs to be compiled (even if they say, that there is a binary, I did not find it):

wget https://nixos.org/releases/patchelf/patchelf-0.9/patchelf-0.9.tar.bz2
tar -xvf patchelf-0.9.tar.bz2 
cd patchelf-0.9/
./configure && make

Afterwards, you'll find an patchelf executable in src/ (which was a rather surprising location for me).

Just add this to the path by PATH=$(pwd)/src:$PATH, get the ld-linux.so.2 from your system, save it to $MY_PLACE/libs/ld-linux.so.2, cd to your Android SDK and execute

patchelf --set-interpreter $MY_PLACE/libs/ld-linux.so.2 build-tools/23.0.1/aapt
patchelf --set-interpreter $MY_PLACE/libs/ld-linux.so.2 build-tools/23.0.1/aidl
patchelf --set-interpreter $MY_PLACE/libs/ld-linux.so.2 build-tools/23.0.1/zipalign

Then, you'll need to set the library path, e.g. by export LD_LIBRARY_PATH=$MY_PLACE/libs/. Afterwards ./gradlew assemble is running fine (for exactly this build tools version).

While this solution works, you'll need to edit every binary (which may be needed later) manually. I assume that there is some magic in multiarch systems which determines which interpreter to use, the 32 or 64 bit one (ldd will return different pathes for the interpreter depending on the file). It would be a better solution to make use of this magic in order to run 32 bit executables without root. Therefore, I'll accept a solution which make it possible to run builds by just changing environment variables and without tampering with the executables.

David Georg Reichelt
  • 963
  • 1
  • 15
  • 36