Android.mk Unable to link with libcrypto

2.4k views Asked by At

Case:

I am building an app which uses libcrypto and libssl. I am trying to use prebuilt libcrypto.so and libssl.so and compile my application.

But I keep getting undefined reference errors.

My App/Android.mk

LOCAL_PATH := $(call my-dir)
my_LOCAL_PATH := $(LOCAL_PATH)
include $(call all-subdir-makefiles)
LOCAL_PATH := $(my_LOCAL_PATH)
common_SRC_FILES := \
    src/foo.c
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(common_SRC_FILES)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../openssl/include
LOCAL_SHARED_LIBRARIES += mylibssl mylibcrypto
include $(BUILD_STATIC_LIBRARY)

My App/mylibssl/Android.mk

Building mylibssl [from a prebuilt libssl.so]

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylibssl
LOCAL_SRC_FILES := libssl.so
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../openssl/include
include $(BUILD_PREBUILT)

My App/mylibcrypto/Android.mk

Building mylibcrypto [from a prebuilt libcrypto.so]

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylibcrypto
LOCAL_SRC_FILES := libcrypto.so
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../openssl/include
include $(BUILD_PREBUILT)

I keep getting

error: undefined reference to 'BIO_new_mem_buf'
error: undefined reference to 'PEM_read_bio_X509_AUX'
error: undefined reference to 'BIO_free'
...

I have spent several hours trying to figure out and am totally stuck. Please help!

1

There are 1 answers

0
jww On

I am building an app which uses libcrypto and libssl... But I keep getting undefined reference errors.

error: undefined reference to 'BIO_new_mem_buf'
error: undefined reference to 'PEM_read_bio_X509_AUX'
error: undefined reference to 'BIO_free'

These are linker errors, and mean you are not linking against the OpenSSL library. Its probably a path problem, assuming you have an Android version of the OpenSSL library available.


If you need an an Android version of the OpenSSL library, then you can build it yourself or find it on Github. To build it yourself, see FIPS Library and Android (just ignore the FIPS stuff). The steps required are (and note the leading dot "." when running the script):

cd openssl-1.0.1f/
wget http://wiki.openssl.org/images/7/70/Setenv-android.sh
chmod a+x *.sh
. ./setenv-android.sh

./config shared no-ssl2 no-hw no-engine --openssldir=/usr/local/ssl/android-18/ <other options>
make depend
make all

For option two, you can search Github with https://www.google.com/q=openssl+android+site:github.com.


Building mylibcrypto [from a prebuilt libcrypto.so]

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mylibcrypto
LOCAL_SRC_FILES := libcrypto.so

This is not going to produce expected results, and will likely result in a crash if you get it to work. The problem is Android uses 0.9.8, and you are probably building against 1.0.1.

What happens is Zygote loads OpenSSL 0.9.8 at startup (its the parent of all Android Java programs). When your app is launched, Zygote is forked so OpenSSL is already mapped into the address space. That means the version of OpenSSL you are carrying around is not loaded. Later, you crash because 0.9.8 and 1.0.1 are not binary compatible (i.e., they are ABI incompatible).

You are correct in building a wrapper shared object (mylibcrypto.so). However, mylibcrypto.so will need to statically link against OpenSSL to avoid the above problem. That is, mylibcrypto.so will need to link against libcrypto.a and libssl.a.