2012-07-28 55 views
4

我对Android非常陌生,编译和链接一般。我不知道哪些细节对我的问题很重要,所以我只会告诉你一切。如果您发现任何奇怪或不正确的情况,请告诉我。Android NDK的未定义引用libssl函数

我在Android-NDK中构建了libcrypto.so和libssl.so库。我编写了使用openssl.so中的函数的本地代码(并且openssl.so使用libssl.so中的函数)。代码编译,但是我连接时收到“未定义的引用”错误:

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

我搜索谷歌和发现了同样的问题一个人如我,她甚至呼吁相同的功能(除非这个人是不适用于Android):http://ubuntuforums.org/showthread.php?t=1081028。我会引用她的帖子中与我的问题相关的部分:

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?

我注意到了这种相同的行为。她通过编译-lssl设置解决了她的问题,该设置告诉编译器使用openssl库。对我来说,要做到这一点,我改变了Android.mk文件的模块从这个:

LOCAL_LDLIBS += -ldl 

这样:

LOCAL_LDLIBS += -lssl -lcrypto -ldl 

我包括-lcrypto只是为了安全起见,因为的libssl取决于libcrypto 。现在,当我运行NDK建造,我收到以下错误:

/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 

此错误表明,“LD”不能libssl.so找到。我的jni目录中有libcrypto.so和libssl.so。我最好想找到一种方法将jni目录添加到“ld”的搜索路径中,但我无法弄清楚。我试图通过将libssl.so和libcrypto.so添加到以下目录来解决此问题:/ android-ndk-r8/platforms/android-8/arch-arm/usr/lib(我相信“ld”在这里搜索for库)。一旦我这样做,我又跑了NDK构建和收到“未定义的引用”错误:

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

从这里,我无能,如何继续。

万一是很重要的,这里是我的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) 

编辑:东西我忘了补充:当我在libcrypto.so使用函数在我的本机代码,代码编译并链接正常。看来我可以在libcrypto.so中使用任何函数。但是,给我带来问题的函数是在libssl.so中。这可能或可能不重要。

回答

8

我解决了这个问题。我所调用的函数“RSA_generate_key”只存在于libcrypto.so的已弃用版本中。我使用的是使用“RSA_generate_key_ex”的较新版本。我发现了这一点,通过对libcrypto.so做readelf:

$ ./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 

之所以仍然编译的程序是因为RSA_generate_key是即使图书馆没有它的OpenSSL/rsa.h的头文件。