2012-07-28 2 views
4

Je suis très nouveau sur Android, la compilation et la liaison en général. Je ne sais pas quels détails sont importants avec mon problème, alors je vais tout vous dire. Si vous voyez quelque chose d'étrange ou incorrect, s'il vous plaît faites le moi savoir.Référence non définie à la fonction libssl avec Android NDK

J'ai construit les bibliothèques libcrypto.so et libssl.so dans l'Android-NDK. J'ai écrit du code natif qui utilise une fonction dans openssl.so (et openssl.so utilise des fonctions dans libssl.so). Le code compile, mais je reçois une erreur « de référence non défini » lors de la liaison:

./obj/local/armeabi/objs/pki_send/pki_send.o: In function `main': 
/home/android/nativeserver/jni/pki_send.c:27: undefined reference to `RSA_generate_key' 
collect2: ld returned 1 exit status 
make: *** [obj/local/armeabi/pki_send] Error 1 

J'ai cherché sur Google et a trouvé une personne avec le même problème que moi, elle est même appeler la même fonction (sauf que cette personne est pas de construction pour Android): http://ubuntuforums.org/showthread.php?t=1081028. Je vais citer la partie de son message ici qui est pertinent à mon problème:

When I remove an argument [to the function which causes the "undefined reference"] the compiler says that there's too few arguments and when I add an argument the compiler says there's too many arguments, so it seems like there is "some" kind of reference to the correct function. There's some linking going on wrongly perhaps?

J'ai remarqué ce même comportement. Elle a résolu son problème en compilant le paramètre -lssl, qui indique au compilateur d'utiliser la bibliothèque openssl. Pour moi, pour cela, j'ai changé le module dans le fichier Android.mk de ceci:

LOCAL_LDLIBS += -ldl 

à ceci:

LOCAL_LDLIBS += -lssl -lcrypto -ldl 

Je -lcrypto inclus juste pour être sûr, puisque dépend libssl de libcrypto . Maintenant, quand je lance NDK-build, je reçois l'erreur suivante:

/home/android/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: cannot find -lssl 
collect2: ld returned 1 exit status 
make: *** [obj/local/armeabi/pki_send] Error 1 

Cette erreur montre que « ld » ne peut pas trouver libssl.so. J'ai libcrypto.so et libssl.so dans mon répertoire jni. Je voulais idéalement trouver un moyen d'ajouter le répertoire jni au chemin de recherche de "ld", mais je ne pouvais pas le comprendre. J'ai essayé de résoudre ce problème en ajoutant libssl.so et libcrypto.so au répertoire suivant:/android-ndk-r8/plates-formes/android-8/arch-arm/usr/lib (je crois que "ld" recherche ici pour bibliothèques). Une fois que je l'ai fait, je courais à nouveau NDK-build et reçu une erreur « de référence non définie »:

./obj/local/armeabi/objs/pki_send/pki_send.o: In function `main': 
/home/android/nativeserver/jni/pki_send.c:27: undefined reference to `RSA_generate_key' 
collect2: ld returned 1 exit status 
make: *** [obj/local/armeabi/pki_send] Error 1 

A partir de là, je suis désemparés quant à la façon de procéder.

Juste au cas où il est important, voici le code dans mon fichier Android.mk:

LOCAL_PATH := $(call my-dir) 
APP_PLATFORM := android-8 

include $(CLEAR_VARS) 

LOCAL_MODULE := crypto 
LOCAL_SRC_FILES := libcrypto.so 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include/ 

include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 

LOCAL_MODULE := ssl 
LOCAL_SRC_FILES := libssl.so 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include/ 

include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 

LOCAL_SRC_FILES := pki_send.c 
LOCAL_MODULE := pki_send 
LOCAL_SHARED_LIBRARIES := ssl crypto 
LOCAL_LDLIBS += -lssl -lcrypto -ldl 

LOCAL_MODULE_TAGS := optional 

include $(BUILD_EXECUTABLE) 

EDIT: j'ai oublié d'ajouter: quand j'utilise des fonctions dans mon code natif dans libcrypto.so, le code compile et lie bien. Il semble que je peux utiliser n'importe quelle fonction dans libcrypto.so. Cependant, la fonction qui me pose des problèmes est dans libssl.so. Cela peut ou peut ne pas être important.

Répondre

8

J'ai résolu le problème. La fonction que j'appelais, "RSA_generate_key", n'existe que dans la version obsolète de libcrypto.so. J'utilisais la nouvelle version qui utilise "RSA_generate_key_ex". J'ai trouvé cela en faisant un readelf sur libcrypto.so:

$ ./arm-linux-androideabi-readelf -all ~/nativeserver/jni/libcrypto.so |grep RSA_generate 
    679: 00089239 992 FUNC GLOBAL DEFAULT 7 RSA_generate_key_ex 
10334: 00089239 992 FUNC GLOBAL DEFAULT 7 RSA_generate_key_ex 

La raison pour laquelle le programme encore compilé est parce que RSA_generate_key est dans le fichier d'en-tête de OpenSSL/rsa.h même si la bibliothèque ne l'a pas.

Questions connexes