J'essaie depuis quelques jours de compiler un binaire ARM Android natif qui s'exécutera sur mon téléphone à l'aide d'une application de terminal. Je veux générer le même type de binaire que les binaires Posix standard installés sur le téléphone comme ls, mkdir etc. J'ai téléchargé le Android NDK sous Mac OS X et j'ai pu compiler de simples binaires ELF sans erreurs . Cependant, lorsque je les transfère sur le téléphone, ils se cassent toujours. C'est-à-dire qu'ils se séparent lorsqu'ils sont compilés avec -static dans GCC. Si je n'utilise pas -static, ils se plaignent de ne pas être liés, etc. En termes simples, ils ne fonctionnent pas.
Mon hypothèse est qu'ils ne se lient pas correctement à la bibliothèque C standard Android. Même si je relie mes binaires à la libc fournie par le NDK, ils ne fonctionnent toujours pas. J'ai lu que Android utilise la bibliothèque Bionic C, et j'ai essayé de télécharger la source pour celle-ci mais je ne sais pas comment construire une bibliothèque à partir d'elle (c'est tout ARM Assembly, semble-t-il).
Est-il vrai que la bibliothèque Android C sur le téléphone est différente de celle fournie avec le NDK Android? Est-ce que celui inclus avec le NDK ne me permet pas de compiler des binaires natifs que je peux exécuter via un terminal? Tout conseil ici est grandement apprécié!
Mise à jour:
J'ai finalement réussi à utiliser GCC 4.7.0 sur Mac OS X. J'ai téléchargé les en-têtes Bionic puis compilé un binaire lié dynamiquement à l'aide de la bibliothèque C fournie avec le NDK Android. J'ai pu obtenir une application de test pour travailler sur le téléphone en utilisant le C lib du téléphone (le binaire était 33K). J'ai également essayé de me lier statiquement à la bibliothèque C de NDK, et cela a également fonctionné.
Pour que tout cela fonctionne, j'ai dû passer -nostdlib à GCC, puis ajouter manuellement crtbegin_dynamic.o et crtend_Android.o à la ligne de commande de GCC. Cela fonctionne comme ceci:
$CC \
$NDK_PATH/usr/lib/crtbegin_dynamic.o \
hello.c -o hello \
$CFLAGS \
$NDK_PATH/usr/lib/crtend_Android.o
Pour les binaires statiques, utilisez "crtbegin_static.o". Ceci est expliqué dans la source crtbegin_dynamic.S/crtbegin_static.S.
Pour cette expérience, j'ai utilisé uniquement GCC 4.7.0 ordinaire et Binutils 2.22. J'ai également compilé GCC avec newlib, mais je ne lie pas du tout mes binaires ARM avec newlib. J'oblige GCC/ld à se connecter directement à la libc fournie avec le NDK Android, ou dans le cas des binaires dynamiques, à la libc sur le téléphone.
Utilisez simplement Android-ndk. Et construisez un Android.mk comme ça. include $(BUILD_EXECUTABLE)
est ce qui lui dit de construire un exécutable au lieu d'un JNI .lib
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
Tout d'abord, assurez-vous d'avoir le NDK:
http://developer.Android.com/tools/sdk/ndk/index.html
Voici la façon la plus simple de compiler un binaire C pour votre téléphone:
http://developer.Android.com/tools/sdk/ndk/index.html
http://www.kandroid.org/ndk/docs/STANDALONE-TOOLCHAIN.html
Habituellement $ NDK (peut être différent) =
Linux:
/Accueil/<user>
/Android-ndk
Mac OS X:
/Utilisateurs/<user>
/Android-ndk
Dans le 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
Utiliser CMake avec le Android NDK est une belle façon de compiler Android applications console).
Téléchargez CMake et Android-cmake (configurez-le comme ceci ). Si votre programme s'appelle main.c, écrivez ce qui suit dans le fichier CMakeLists.txt
:
project(test)
cmake_minimum_required(VERSION 2.8)
add_executable(test ./main.c)
et courir cmake -DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN .
Vous aurez alors un Makefile pour votre programme, vous pouvez exécuter make
pour avoir votre test
exécutable.
Essayez si si le wrapper agcc peut vous aider comme référencé dans le blog Android-tricks . Selon l'article de blog, vous souhaitez utiliser la bibliothèque bionique, mais celle déjà installée sur le téléphone , pas une version compilée séparément.