Android ndk 无法使用使用android ndk的预构建共享库运行可执行文件
我试图构建一个可执行文件,它依赖于android的C语言中的共享库。我想在android shell上运行可执行文件。 我首先使用android-ndk构建了可执行文件,我使用android-ndk-r16b,然后使用adb-push将ndk生成的文件放在我的android设备上,然后使用adb shell尝试运行可执行文件 我正在Ubuntu 14.04上构建。 我使用apt get安装了android arm工具链: 这是我的档案: 共享库:libcal.so cal.c:Android ndk 无法使用使用android ndk的预构建共享库运行可执行文件,android-ndk,java-native-interface,android-shell,Android Ndk,Java Native Interface,Android Shell,我试图构建一个可执行文件,它依赖于android的C语言中的共享库。我想在android shell上运行可执行文件。 我首先使用android-ndk构建了可执行文件,我使用android-ndk-r16b,然后使用adb-push将ndk生成的文件放在我的android设备上,然后使用adb shell尝试运行可执行文件 我正在Ubuntu 14.04上构建。 我使用apt get安装了android arm工具链: 这是我的档案: 共享库:libcal.so cal.c: #include
#include "cal.h"
int add(int a , int b)
{
return (a + b);
}
int sub(int a, int b)
{
return (a - b);
}
cal.h:
int add(int a , int b);
int sub(int a, int b);
生成文件:
CXX=arm-linux-androideabi-gcc
CXXFLAGS=-fPIC -Wall -I. -c
LDFLAGS=-shared
SOURCES=./cal.c
OBJECTS=$(SOURCES:.c=.o)
TARGET_LIB=libcal.so
all: $(SOURCES) $(TARGET_LIB)
$(TARGET_LIB): $(OBJECTS)
$(CXX) -o $@ $(OBJECTS) $(LDFLAGS)
.c.o:
$(CXX) $(CXXFLAGS) $< -o $@
.PHONY: clean
clean:
@rm -f $(TARGET_LIB) $(OBJECTS)
Application.mk
APP_ABI := armeabi-v7a
APP_PLATFORM := android-19
然后在运行$ndk build时,这是我的输出
rohith@rohith-Lenovo-G50-80:~/example2/hello/jni$ ndk-build
[armeabi-v7a] Prebuilt : libcal.so <= jni/../../library/
[armeabi-v7a] Install : libcal.so => libs/armeabi-v7a/libcal.so
[armeabi-v7a] Compile thumb : test <= test.c
[armeabi-v7a] Executable : test
[armeabi-v7a] Install : test => libs/armeabi-v7a/test
rohith@rohith-Lenovo-G50-80:~/example2/hello/jni$ cd ../libs/armeabi-v7a/
rohith@rohith-Lenovo-G50-80:~/example2/hello/libs/armeabi-v7a$ ls
libcal.so test
rohith@rohith-Lenovo-G50-80:~/example2/hello/libs/armeabi-v7a$
为什么它会链接到我的笔记本电脑的路径
如果有人能告诉我我做错了什么,或者给我一些关于他们如何做类似事情的建议,我将不胜感激
我的实际任务要求我链接更复杂的共享库,并在AndroidShell上运行一个可执行文件。如果我能得到一个简单的,我不知道该怎么做。太好了。库没有正确构建。SONAME路径的这种问题。它是在Android API 23上的一个特殊事件之后出现的
如果出于任何原因,您无法使用最新的NDK重建此库,您可以尝试使用该实用程序将SONAME添加到现有二进制文件。我尝试了Alex Cohen指定的方法之一 对NDK生成的可执行文件运行$readelf-d test时,输出如下:
(...)
0x00000004 (HASH) 0x41c
0x00000001 (NEEDED) Shared library: [/home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
(...)
共享库的路径已附加到其名称。因此,为了将其改为libcal,我使用了
以下是我使用的命令:
$patchelf --remove-needed /home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so test
$patchelf --add-needed libcal.so test
注意:这可能不是完美的解决方案。在更改库名后运行readelf-d测试时,我得到了另一个字段,在可执行文件工作时,我不太在意它
rohith@rohith-Lenovo-G50-80:~/example2/hello/libs/armeabi-v7a$ readelf -d test
Dynamic section at offset 0x4000 contains 32 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libcal.so]
0x0000001d (RUNPATH) Library runpath: [/home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so:./libcal.so]
0x00000003 (PLTGOT) 0x2fcc
0x00000002 (PLTRELSZ) 80 (bytes)
0x00000017 (JMPREL) 0x50c
0x00000014 (PLTREL) REL
0x00000011 (REL) 0x4ac
0x00000012 (RELSZ) 96 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 10
0x00000015 (DEBUG) 0x0
0x00000006 (SYMTAB) 0x224
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0x4130
0x0000000a (STRSZ) 347 (bytes)
0x00000004 (HASH) 0x41c
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libm.so]
添加了额外的字段类型运行路径谢谢@Alex Cohn。我使用patchelf更改共享库的名称。我将通过我的回答详细说明,这个想法是修补libcal.so头。
rohith@rohith-Lenovo-G50-80:~/example/hello/jni$ ndk-build
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-14.
[arm64-v8a] Prebuilt : libcal.so <= jni/../../library/
[arm64-v8a] Install : libcal.so => libs/arm64-v8a/libcal.so
[arm64-v8a] Compile : test <= test.c
[arm64-v8a] Executable : test
/home/rohith/example/hello/obj/local/arm64-v8a/libcal.so: error adding symbols: File in wrong format
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [/home/rohith/example/hello/obj/local/arm64-v8a/test] Error 1
rohith@rohith-Lenovo-G50-80:~/example2/hello/libs/armeabi-v7a$ ls
libcal.so test
rohith@rohith-Lenovo-G50-80:~/example2/hello/libs/armeabi-v7a$ cd ..
rohith@rohith-Lenovo-G50-80:~/example2/hello/libs$ adb push armeabi-v7a /data/local/rohith
push: armeabi-v7a/libcal.so -> /data/local/rohith/libcal.so
push: armeabi-v7a/test -> /data/local/rohith/test
2 files pushed. 0 files skipped.
134 KB/s (11088 bytes in 0.080s)
rohitht@rohith-Lenovo-G50-80:~/example2/hello/libs$ adb shell
root@tcc897x:/ # cd /data/local/rohith
root@tcc897x:/data/local/rohith # ls
libcal.so
test
root@tcc897x:/data/local/rohith # export LD_LIBRARY_PATH=.
root@tcc897x:/data/local/rohith # ./test
CANNOT LINK EXECUTABLE: could not load library "/home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so" needed by "./test"; caused by library "/home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so" not found
1|root@tcc897x:/data/local/rohith #
(...)
0x00000004 (HASH) 0x41c
0x00000001 (NEEDED) Shared library: [/home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so]
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libstdc++.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
(...)
$patchelf --remove-needed /home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so test
$patchelf --add-needed libcal.so test
rohith@rohith-Lenovo-G50-80:~/example2/hello/libs/armeabi-v7a$ readelf -d test
Dynamic section at offset 0x4000 contains 32 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libcal.so]
0x0000001d (RUNPATH) Library runpath: [/home/rohith/example2/hello/obj/local/armeabi-v7a/libcal.so:./libcal.so]
0x00000003 (PLTGOT) 0x2fcc
0x00000002 (PLTRELSZ) 80 (bytes)
0x00000017 (JMPREL) 0x50c
0x00000014 (PLTREL) REL
0x00000011 (REL) 0x4ac
0x00000012 (RELSZ) 96 (bytes)
0x00000013 (RELENT) 8 (bytes)
0x6ffffffa (RELCOUNT) 10
0x00000015 (DEBUG) 0x0
0x00000006 (SYMTAB) 0x224
0x0000000b (SYMENT) 16 (bytes)
0x00000005 (STRTAB) 0x4130
0x0000000a (STRSZ) 347 (bytes)
0x00000004 (HASH) 0x41c
0x00000001 (NEEDED) Shared library: [libc.so]
0x00000001 (NEEDED) Shared library: [libm.so]