我正在使用 linaro 和 codesourcery 工具链为 android 进行交叉编译,我什至在提供 -static
后发现这里的问题似乎来自 glibc 动态链接 libnss_* 库
。
这是我的代码
#include <sys/types.h>
#include <pwd.h>
int main(){
struct passwd *pw = getpwnam("root");
return 0;
}
运行以下命令
arm-linux-gnueabihf-gcc -static pwnam_test.c -lc -o pwtest
跟踪后得到如下输出
11455 uname(0xf6ffeb70) = 0
11455 brk(NULL) = 0x0006d000
11455 brk(0x0006dd00) = 0x0006dd00
11455 brk(0x0008ed00) = 0x0008ed00
11455 brk(0x0008f000) = 0x0008f000
11455 套接字 (1,526337,0,0,445504,319244) = 3
11455 connect(3,0xf6ffea30,110) = -1 errno=2(没有那个文件或目录)
11455 关闭(3)= 0
11455 套接字 (1,526337,0,1,445504,0) = 3
11455 connect(3,0xf6ffeb50,110) = -1 errno=2(没有那个文件或目录)
11455 关闭(3)= 0
11455 打开(“/etc/nsswitch.conf”,O_RDONLY|O_CLOEXEC)= 3
11455 fcntl64(3,F_GETFD)= 1
11455 fstat64(3,0xf6ffeb78) = 0
11455 mmap2(NULL,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0)= 0xf67fe000
11455 读取(3,0xf67fe000,4096)= 513
11455 读取(3,0xf67fe000,4096)= 0
11455 关闭(3)= 0
11455 门 map (0xf67fe000,4096)= 0
11455 打开(“/etc/ld.so.cache”,O_RDONLY|O_CLOEXEC)= 3
11455 fstat64(3,0xf6ffe450) = 0
11455 mmap2(NULL,88624,PROT_READ,MAP_PRIVATE,3,0) = 0xf67e9000
11455 关闭(3)= 0
11455 access("/etc/ld.so.nohwcap",F_OK) = -1 errno=2(没有那个文件或目录)
11455 open("/lib/arm-linux-gnueabihf/libnss_compat.so.2",O_RDONLY|O_CLOEXEC) = -1 errno=2(没有这样的文件或目录)
11455 stat64("/lib/arm-linux-gnueabihf",0xf6ffe488) = -1 errno=2(没有那个文件或目录)
11455 open("/usr/lib/arm-linux-gnueabihf/libnss_compat.so.2",O_RDONLY|O_CLOEXEC) = -1 errno=2(没有这样的文件或目录)
11455 stat64("/usr/lib/arm-linux-gnueabihf",0xf6ffe488) = -1 errno=2(没有那个文件或目录)
11455 open("/lib/libnss_compat.so.2",O_RDONLY|O_CLOEXEC) = -1 errno=2(没有这样的文件或目录)
11455 stat64("/lib",0xf6ffe488) = 0
11455 open("/usr/lib/libnss_compat.so.2",O_RDONLY|O_CLOEXEC) = -1 errno=2(没有那个文件或目录)
11455 stat64("/usr/lib",0xf6ffe488) = 0
11455 门 map (0xf67e9000,88624)= 0
11455 退出组(0)
我怎样才能静态链接所有动态所需的库,或者我是否需要交叉编译 glibc?
好吧,我不赞成使用 NDK,因为我试图以某种方式交叉编译 nginx,但在访问 localhost:8080 时 nginx 没有响应
最佳答案
即使您使用 -static
,glibc 仍然会使用 dlopen
来使用本地库来处理 DNS 之类的事情。
恐怕你无法阻止它这样做;它就是这样。尝试在 Android 上使用基于 glibc 的 Linux 工具链可能是错误的做法(尽管如果您愿意,您当然可以将 glibc 安装到 Android 中——比如说,安装到 chroot 中,或者使用替代的 -Wl,-rpath
和 -Wl,--dynamic-linker
设置)。
请注意,传递 -lc
通常是多余的(尽管我很惊讶您不必传递 -ldl
即可使链接正常工作)。
我建议您获得一个真正的 Android 工具链,配置为与 Bionic C 库一起使用,然后使用它。 Google NDK 可以使用,Linaro 也可以使用(他们同时使用 Android 和 Linux,因此请确保您使用的是正确的)。所有工具链都使用 GCC,因此您应该可以毫无问题地了解如何使用它。
关于android - 静态链接的二进制文件需要共享库 libnss,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22452755/