几天来,我一直在尝试编译一个本机 ARM Android 二进制文件,该二进制文件将使用终端应用程序在我的手机上执行。我想生成与安装在手机上的标准 Posix 二进制文件(如 ls、mkdir 等)相同类型的二进制文件。我已经在 Mac OS X 下下载了 Android NDK,并且能够编译简单的 ELF 二进制文件而不会出错。但是,当我将它们转移到手机时,它们总是出现段错误。也就是说,在 GCC 中使用 -static 编译时会出现段错误。如果我不使用 -static,他们会抱怨没有被链接,等等。简单地说,他们不工作。
我的假设是它们没有正确链接到 Android 标准 C 库。即使我将我的二进制文件与 NDK 提供的 libc 链接起来,它们仍然不起作用。我读到 Android 使用 Bionic C 库,并尝试下载它的源代码,但我不确定如何从中构建一个库(似乎都是 ARM 程序集)。
手机上的Android C库和Android NDK提供的库是不是真的不一样?NDK 中包含的那个是否不允许我编译可以通过终端执行的本机二进制文件?非常感谢这里的任何指导!
更新:
我终于在 Mac OS X 上使用 GCC 4.7.0 让它工作了。我下载了 Bionic 头文件,然后使用 Android NDK 附带的 C 库编译了一个动态链接的二进制文件。我能够使用手机的 C 库(二进制文件为 33K)让测试应用程序在手机上运行。我还尝试静态链接到 NDK 的 C 库,这也有效。
为了让这一切正常工作,我必须将 -nostdlib 传递给 GCC,然后手动将 crtbegin_dynamic.o 和 crtend_android.o 添加到 GCC 的命令行。它的工作原理是这样的:
$CC \
$NDK_PATH/usr/lib/crtbegin_dynamic.o \
hello.c -o hello \
$CFLAGS \
$NDK_PATH/usr/lib/crtend_android.o
对于静态二进制文件,使用“crtbegin_static.o”。这在 crtbegin_dynamic.S/crtbegin_static.S 源中进行了解释。
对于这个实验,我只使用了普通的 'ol GCC 4.7.0 和 Binutils 2.22。我还用 newlib 编译了 GCC,但我实际上并没有将我的 ARM 二进制文件与 newlib 链接。我强制 GCC/ld 直接链接到 Android NDK 提供的 libc,或者在动态二进制文件的情况下,链接到手机上的 libc。