简体   繁体   中英

Compiling shared and static libraries into a shared library using the Android NDK

I have come across a problem with trying to compile cURL with SSL support into an app.

So far, I have successfully compiled the openSSL package into libcrypt.so and libssl.so.

I believe I have successfully compiled a version of libcurl.a with SSL support using the configure script and running it through the cross-chain compiler found in the NDK (under a linux environment).

Now, I am attempting to write a .so library under Eclipse that can be called by the Java code of an Android App.

Here is the file structure so far:

Project Folder ---> jni ---> include ---> curl ---> curl headers
                         |            |
                         |             -> openssl ---> ssl and crypto headers
                         |
                          -> libcrypto.so
                          -> libssl.so
                          -> libcurl.a
                          -> jniProcessRequest.c
                          -> Android.mk

Android.mk reads:

LOCAL_PATH := $(call my-dir)
MY_PATH := $(LOCAL_PATH)
include $(CLEAR_VARS)
LOCAL_PATH := $(MY_PATH)

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

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

include $(CLEAR_VARS)
LOCAL_MODULE := curl
LOCAL_SRC_FILES := libcurl.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/curl/
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := JNIProcessRequest
LOCAL_SRC_FILES := JNIProcessRequest.c
LOCAL_SHARED_LIBRARIES := crypto ssl
LOCAL_STATIC_LIBRARIES := curl
LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

jniProcessRequest.c:

#include <jni.h>
#include <stdlib.h>
#include "include/curl/curl.h"
#include <android/log.h>

JNIEXPORT void JNICALL Java_com_example_jniprocessrequest_MainActivity_jniProcessRequest(JNIEnv * env, jobject obje){
CURL *conn;
conn = curl_easy_init();
}

Every time I attempt to compile the above, I have undefined reference errors in Eclipse:

make: *** [obj/local/armeabi/libJNIProcessRequest.so] Error 1
undefined reference to 'curl_easy_init'

I am thinking this is some sort of linkage error but am struggling to find where the error is occurring. I have spent nearly two days trying all different methods of placing the shared libraries in differing places, switching the static libcurl with a shared libcurl, altering the Android.mk file and following tutorials on how to get cURL working in Android.

Any help would be greatly appreciated!

I believe that the problem was stemming from an incorrectly built libcurl.a static library. I replaced my library with one that was compiled by a user on GitHub and without changing any code, the linkage errors disappeared.

You use curl as a prebuilt module.

As stated by the NDK documentation you should take care to wrap it under include $(CLEAR_VARS) and (most importantly) include $(PREBUILT_STATIC_LIBRARY) directives as follow:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.a
include $(PREBUILT_STATIC_LIBRARY)

Right after take care to wrap your JNIProcessRequest module with include $(CLEAR_VARS) and include $(BUILD_SHARED_LIBRARY) .

For more details please refer to the docs/PREBUILTS.html section that you can find within your Android NDK folder (it looks like this ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM