想要编译本机 Android 二进制文件,我可以在手机的终端中运行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10798357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Want to compile native Android binary I can run in terminal on the phone
提问by Synthetix
I've been trying for a couple days to compile a native ARM Android binary that will execute on my phone using a terminal application. I want to generate the same type of binary as the standard Posix binaries installed on the phone like ls, mkdir etc. I've downloaded the Android NDK under Mac OS X and have been able to compile simple ELF binaries without errors. However, when I transfer them to the phone, they always segfault. That is, they segfault when compiled with -static in GCC. If I don't use -static, they complain about not being linked, etc. Put simply, they don't work.
我一直在尝试编译一个本地 ARM Android 二进制文件,该二进制文件将使用终端应用程序在我的手机上执行。我想生成与手机上安装的标准 Posix 二进制文件相同类型的二进制文件,如 ls、mkdir 等。我已经在 Mac OS X 下下载了 Android NDK,并且能够编译简单的 ELF 二进制文件而不会出错。但是,当我将它们传输到手机时,它们总是出现段错误。也就是说,它们在 GCC 中使用 -static 编译时会出现段错误。如果我不使用 -static,他们会抱怨没有被链接等等。简而言之,他们不起作用。
My hypothesis is that they are not linking to the Android standard C library properly. Even though I am linking my binaries with the libc provided by the NDK, they still don't work. I read that Android uses the Bionic C library, and tried to download source for it but I'm not sure how to build a library from it (it's all ARM assembly, it seems).
我的假设是它们没有正确链接到 Android 标准 C 库。即使我将我的二进制文件与 NDK 提供的 libc 链接起来,它们仍然不起作用。我读到 Android 使用 Bionic C 库,并尝试下载它的源代码,但我不确定如何从中构建库(似乎都是 ARM 程序集)。
Is it true that the Android C library on the phone is different from the one provided with the Android NDK? Will the one included with the NDK not allow me to compile native binaries I can execute through a terminal? Any guidance here is greatly appreciated!
手机上的Android C库和Android NDK自带的库是不是真的不一样?NDK 中包含的那个不允许我编译可以通过终端执行的本机二进制文件吗?非常感谢这里的任何指导!
Update:
更新:
I finally got this to work using GCC 4.7.0 on Mac OS X. I downloaded the Bionic headers and then compiled a dynamically linked binary using the C library that comes with the Android NDK. I was able to get a test app to work on the phone using the phone's C lib (the binary was 33K). I also tried to statically link against the NDK's C library, and that also worked.
我终于在 Mac OS X 上使用 GCC 4.7.0 让它工作了。我下载了 Bionic 头文件,然后使用 Android NDK 附带的 C 库编译了一个动态链接的二进制文件。我能够使用手机的 C 库(二进制文件为 33K)让测试应用程序在手机上运行。我还尝试静态链接 NDK 的 C 库,这也有效。
In order to get this all working I had to pass -nostdlib to GCC and then manually add crtbegin_dynamic.o and crtend_android.o to GCC's command line. It works something like this:
为了让这一切正常工作,我必须将 -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
For static binaries, use "crtbegin_static.o." This is explained in the crtbegin_dynamic.S/crtbegin_static.S source.
对于静态二进制文件,请使用“crtbegin_static.o”。这在 crtbegin_dynamic.S/crtbegin_static.S 源中有解释。
For this experiment, I only used plain 'ol GCC 4.7.0 and Binutils 2.22. I also compiled GCC with newlib, but I am not actually linking my ARM binaries with newlib at all. I am forcing GCC/ld to link directly to the libc provided with the Android NDK, or in the case of dynamic binaries, to the libc on the phone.
对于这个实验,我只使用了普通的 'ol GCC 4.7.0 和 Binutils 2.22。我也用 newlib 编译了 GCC,但我实际上并没有将我的 ARM 二进制文件与 newlib 链接起来。我强制 GCC/ld 直接链接到 Android NDK 提供的 libc,或者在动态二进制文件的情况下,链接到手机上的 libc。
采纳答案by SonicBison
Just use the android-ndk. And build a Android.mk like so.
include $(BUILD_EXECUTABLE)
is what tells it build a executable instead of a JNI .lib
只需使用android-ndk。并像这样构建一个Android.mk。
include $(BUILD_EXECUTABLE)
是什么告诉它构建可执行文件而不是 JNI .lib
Android.mk
安卓.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
回答by Jared Burrows
First, make sure you have the NDK:
首先,确保你有 NDK:
http://developer.android.com/tools/sdk/ndk/index.html
http://developer.android.com/tools/sdk/ndk/index.html
Here is the easiest way to compile a C binary for your phone:
这是为您的手机编译 C 二进制文件的最简单方法:
http://developer.android.com/tools/sdk/ndk/index.html
http://developer.android.com/tools/sdk/ndk/index.html
http://www.kandroid.org/ndk/docs/STANDALONE-TOOLCHAIN.html
http://www.kandroid.org/ndk/docs/STANDALONE-TOOLCHAIN.html
Usually $NDK(may be different) =
通常$NDK(可能会有所不同)=
Linux:
Linux:
/home/<user>
/android-ndk
/home/ <user>
/android-ndk
Mac OS X:
Mac OS X:
/Users/<user>
/android-ndk
/用户/ <user>
/android-ndk
In Terminal:
在终端:
# 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
回答by gfour
Using CMake with the Android NDK is a nice way to compile Android console applications.
将 CMake 与 Android NDK 结合使用是编译 Android 控制台应用程序的好方法。
Download CMakeand android-cmake(set it up like this). If your program is called main.c, then write the following in file CMakeLists.txt
:
下载CMake和android-cmake(像这样设置)。如果您的程序名为 main.c,则在文件中写入以下内容CMakeLists.txt
:
project(test)
cmake_minimum_required(VERSION 2.8)
add_executable(test ./main.c)
and run cmake -DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN .
并运行 cmake -DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN .
You will then have a Makefile for your program, you can run make
to have your test
executable.
然后,您将拥有程序的 Makefile,您可以运行make
以获取test
可执行文件。
回答by Prof. Falken contract breached
Try if if the agcc wrappercan help you as referenced in the Android-tricksblog. According to the blog post you want to use the bionic library, but the one already installed on the phone, not some separately compiled version.
试试看agcc 包装器是否可以帮助您,如Android-tricks博客中所述。根据博文你要使用仿生库,但手机上已经安装了一个,而不是一些单独编译的版本。