35

几天来,我一直在尝试编译一个本机 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。

4

4 回答 4

20

只需使用 android-ndk。并像这样构建一个Android.mk。 include $(BUILD_EXECUTABLE)是什么告诉它构建可执行文件而不是 JNI .lib

安卓.mk

ifneq ($(TARGET_SIMULATOR),true)

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_CFLAGS += -Wall


LOCAL_LDLIBS := -L$(LOCAL_PATH)/lib -llog -g

LOCAL_C_INCLUDES := bionic
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include

LOCAL_SRC_FILES:= main.cpp

LOCAL_MODULE := mycmd

include $(BUILD_EXECUTABLE)

endif  # TARGET_SIMULATOR != true
于 2012-06-09T23:16:11.673 回答
17

首先,确保您有 NDK:

http://developer.android.com/tools/sdk/ndk/index.html

这是为您的手机编译 C 二进制文件的最简单方法:

http://developer.android.com/tools/sdk/ndk/index.html

http://www.kandroid.org/ndk/docs/STANDALONE-TOOLCHAIN.html

通常$NDK(可能不同)=

Linux:

/home/ <user>/android-ndk

Mac OS X:

/用户/ <user>/android-ndk

在终端:

# create tool-chain - one line
# New method in ndk 12.
$NDK/build/tools/make_standalone_toolchain.py --arch arm --install-dir=/tmp/my-android-toolchain
# Old method.
#$NDK/build/tools/make-standalone-toolchain.sh --platform=android-3 --install-dir=/tmp/my-android-toolchain

# add to terminal PATH variable
export PATH=/tmp/my-android-toolchain/bin:$PATH

# make alias CC be the new gcc binary
export CC=arm-linux-androideabi-gcc

# compile your C code(I tried hello world)
$CC -o foo.o -c foo.c

# push binary to phone
adb push foo.o /data/local/tmp

# execute binary
adb /data/local/tmp/foo.o
于 2013-05-28T05:36:16.967 回答
3

将 CMake 与 Android NDK 一起使用是编译 Android 控制台应用程序的好方法。

下载CMakeandroid-cmake像这样设置)。如果您的程序名为 main.c,则在文件中写入以下内容CMakeLists.txt

project(test)
cmake_minimum_required(VERSION 2.8)
add_executable(test ./main.c)

并运行cmake -DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN .

然后,您将拥有程序的 Makefile,您可以运行make以获取test可执行文件。

于 2012-05-30T13:26:25.543 回答
0

尝试如果agcc 包装器可以帮助您,如Android-tricks博客中所引用的那样。根据博客文章你想使用仿生库,但是手机上已经安装了一个,而不是一些单独编译的版本。

于 2012-05-29T12:07:18.113 回答