使用32位Android SDK作为用户

时间:2019-01-29 13:30:46

标签: android linux

我想以CentOS上的用户身份使用SDK 23.0.3编译Android Apps。不幸的是,每次build-tools/23.0.3/aapt运行时,它都会返回

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

问题似乎是需要安装32位库。如果我具有sudo权限(在Ubuntu上),则可以运行sudo apt install libc6-i386 lib32stdc++6 lib32gcc1(如CentOS 64 bit bad ELF interpreter中所述),但是不幸的是,我在要编译的计算机上没有sudo。

我假设我可以获取使用的库(如https://www.cs.virginia.edu/~dww4s/articles/ld_linux.html中所述),然后通过设置LD_LIBRARY_PATH(如http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html中的描述)来替​​换使用的库。我通过

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

并将其复制到/home/test。然后我运行了export LD_LIBRARY_PATH=/home/test,但是随后aapt返回了相同的错误。

我尝试的另一件事是获取和提取库(在Ubuntu上):

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

然后又将LD_LIBARY_PATH设置为/home/test/lib:/home/test/lib32,这也没有用。

这可以由docker容器复制:先运行docker run -it ubuntu bash,然后

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 ..

用于设置。然后,build-tools/23.0.3/aapt返回

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

与CentOS(Can not run android/sdk/build-tools/23.0.2/aapt)中的问题相同:缺少32位库。

有人可以告诉我添加库的正确方法是什么吗?

编辑 由于解释器通常会/lib/ld-linux.so.2开始解释文件,因此需要替换它。如果我如上所述手动提取所有.so文件,请将它们放入lib/中并运行

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

正确执行了aapt-command。不幸的是,这还不足以构建:

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

再次返回ELF错误,因为gradle-wrapper(和Java等)是64位二进制文​​件。

2 个答案:

答案 0 :(得分:0)

glibc.i686可从基础存储库中获得:

$ 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

在不可能提供基本依赖性的情况下,该集群是无用的。当然它将需要安装在所有节点上;尽管x86_64库的glibc版本具有相同的版本号,但是它破坏某些内容的可能性很小。

答案 1 :(得分:0)

问题是,elf文件的标头(例如aapt)包含指向解释器的链接(例如/lib/ld-linux.2.so)。需要替换此链接才能执行,但对于32位elf二进制文件,仅。 Gradle和Java仍需要使用其常规的64位解释器执行。由于被调用的进程(例如aapt)是子进程,因此无法直接调用另一个解释器。

一种可能的解决方案是使用跳动(https://nixos.org/patchelf.html)。首先,需要对其进行编译(即使他们说有二进制文件,但我没有找到它):

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

然后,您将在src /中找到一个patchelf可执行文件(对我来说这是一个非常令人惊讶的位置)。

只需通过PATH=$(pwd)/src:$PATH将其添加到路径,从系统中获取ld-linux.so.2,将其保存到$MY_PLACE/libs/ld-linux.so.2,cd到您的Android SDK并执行

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

然后,您需要设置库路径,例如由export LD_LIBRARY_PATH=$MY_PLACE/libs/。之后./gradlew assemble运行正常(对于此构建工具版本而言)。

尽管此解决方案有效,但您需要手动编辑每个二进制文件(以后可能需要)。我假设在多体系结构系统中,使用32或64位解释器(决定ldd会根据文件返回不同的路径)决定了使用哪种解释器。最好利用此魔术来运行32位可执行文件而无需root用户。因此,我将接受一个解决方案,该解决方案使得仅通过更改环境变量而无需篡改可执行文件即可运行构建。