我想以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位二进制文件。
答案 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用户。因此,我将接受一个解决方案,该解决方案使得仅通过更改环境变量而无需篡改可执行文件即可运行构建。