2012-05-29 10 views
27

He intentado durante un par de días para compilar un ARM nativo de Android ARM que se ejecutará en mi teléfono usando una aplicación de terminal. Quiero generar el mismo tipo de binario que los binarios estándar de Posix instalados en el teléfono como ls, mkdir, etc. He descargado el NDK de Android bajo Mac OS X y he podido compilar binarios ELF simples sin errores. Sin embargo, cuando los transfiero al teléfono, siempre segfault. Es decir, segfault cuando se compila con -static en GCC. Si no uso -estático, se quejan de que no están vinculados, etc. En pocas palabras, no funcionan.Quiero compilar un binario nativo de Android Puedo ejecutarlo en la terminal en el teléfono

Mi hipótesis es que no están enlazando correctamente a la biblioteca estándar C de Android. Aunque estoy vinculando mis binarios con la libc proporcionada por el NDK, todavía no funcionan. Leí que Android usa la biblioteca Bionic C, y traté de descargar la fuente para ello, pero no estoy seguro de cómo crear una biblioteca a partir de ella (parece que todo es ensamblado ARM).

¿Es cierto que la biblioteca de Android C en el teléfono es diferente de la proporcionada con el NDK de Android? ¿El que se incluye con el NDK no me permite compilar los binarios nativos que puedo ejecutar a través de un terminal? Cualquier orientación aquí es muy apreciada!

Actualización:

finalmente conseguí que esto funcione usando GCC 4.7.0 en Mac OS X. He descargado los encabezados de Bionic y luego compilado un binario enlazado dinámicamente utilizando la biblioteca de C que viene con el NDK de Android . Pude obtener una aplicación de prueba para que funcionara en el teléfono usando la biblioteca C del teléfono (el binario era de 33K). También traté de vincular estáticamente contra la biblioteca C de NDK, y eso también funcionó.

Para que todo esto funcione, tuve que pasar -nostdlib a GCC y luego agregar manualmente crtbegin_dynamic.o y crtend_android.o a la línea de comandos de GCC. Funciona así:

$CC \ 
$NDK_PATH/usr/lib/crtbegin_dynamic.o \ 
hello.c -o hello \ 
$CFLAGS \ 
$NDK_PATH/usr/lib/crtend_android.o 

Para binarios estáticos, utilice "crtbegin_static.o." Esto se explica en la fuente crtbegin_dynamic.S/crtbegin_static.S.

Para este experimento, utilicé simplemente 'ol GCC 4.7.0 y Binutils 2.22. También compilé GCC con newlib, pero en realidad no estoy vinculando mis binarios ARM con newlib. Estoy forzando a GCC/ld a vincular directamente a la libc proporcionada con Android NDK, o en el caso de los binarios dinámicos, a la libc en el teléfono.

+0

FYI, si se configura una acumulación como si estuviera haciendo una biblioteca JNI (ver los ejemplos en la distribución NDK) y cambiar BUILD_SHARED_LIBRARY en el Android.mk a BUILD_EXECUTABLE obtendrá un ejecutable, aunque esta es una función no oficial (podría desaparecer, etc.) del sistema de compilación ndk. –

+0

Posible duplicado de [¿Cómo puedo ejecutar C binary (archivo ejecutable) en Android desde Android Shell] (http://stackoverflow.com/questions/9868309/how-can-i-run-c-binary-executable-file- in-android-from-android-shell) –

Respuesta

18

Simplemente use el android-ndk.Y crea un Android.mk como tal. include $(BUILD_EXECUTABLE) es lo que dice que construir un ejecutable en lugar de una JNI .LIB

Android.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 
+0

Esta fue la solución para mí. He estado jugando con agcc sin éxito. Esto parece aprovechar el sistema de compilación de Android ... ¿Hay alguna explicación sobre cómo funciona en alguna parte? ¡Gracias! –

+0

$ (NDK_ROOT) /docs/ANDROID-MK.html describe cuáles son todas las macros. – SonicBison

+0

hay un 'endif' extra – dashesy

0

Intente si el agcc wrapper puede ayudarlo como se hace referencia en el blog Android-tricks. De acuerdo con la publicación del blog, usted quiere usar la biblioteca biónica, pero la que está ya está instalada en el teléfono, no en alguna versión compilada por separado.

+0

http://www.crystax.net/android/ndk-r3.php <- también puede ser útil –

+0

¿Por qué utilizar Crystax en este caso en lugar de NDK oficial? –

+0

Sin una razón especial, a veces es útil probar diferentes cosas al experimentar y aprender. Es por eso que acabo de hacer un comentario. –

3

Usar CMake con Android NDK es una buena forma de compilar aplicaciones de consola de Android.

Descargar CMake y android-cmake (configúralo like this). Si el programa se llama main.c, a continuación, escribir lo siguiente en el archivo CMakeLists.txt:

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

y ejecutar cmake -DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN .

A continuación, tendrá un Makefile para su programa, puede ejecutar make tener su test ejecutable .

14

En primer lugar, asegúrese de que tiene el NDK:

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

Aquí es el La forma más fácil de compilar un C binario para su teléfono:

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

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

Por lo general, $ NDK (pueden ser diferentes) =

Linux:

/home/<user>/android-NDK

Mac OS X:

/Users/<user>/andro id-NDK

En la 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 
+0

... ¿está ejecutando un * objeto archivo * allí? Sin vincularlo? ¿Eso realmente funciona? –

+1

Sí, parece que sí. Lo más probable es que necesite eliminar el '-c'. Escribí esto hace un tiempo. –

Cuestiones relacionadas