繁体   English   中英

想编译原生安卓二进制我可以在手机终端运行

[英]Want to compile native Android binary I can run in terminal on the phone

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

只需使用 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

首先,确保您有 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:

/Users/ <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

将 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可执行文件。

在 CMake 中,您可以使用工具链文件进行交叉构建。

来自谷歌开发者

cmake \
    -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
    -DANDROID_ABI=$ABI \
    -DANDROID_PLATFORM=android-$MINSDKVERSION \
    $OTHER_ARGS

CMake 有自己的内置 NDK 支持。 在 CMake 3.21 之前,Android 不支持此工作流程,并且经常会因新的 NDK 版本而中断。 从 CMake 3.21 开始,实现被合并。

从 cmake 3.21 开始,您可以:

mkdir build
cd build
cmake ..
  -DCMAKE_SYSTEM_NAME=Android
  -DCMAKE_SYSTEM_VERSION=23 # API level. optional, recommanded
  -DCMAKE_ANDROID_NDK=path/to/ndk
  -DCMAKE_ANDROID_ARCH=arm # optional, recommanded
  -DCMAKE_ANDROID_ARCH_ABI=armeabi # optional, recommanded

注意:在上面的命令中,行尾( <line feed> )没有被转义,请不要直接在你的 shell 中复制粘贴这个命令

有关变量、可能值和确定算法的更多信息,请参阅使用 NDK 为 Android 进行交叉编译

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM