3

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!

jww
  • 97,681
  • 90
  • 411
  • 885
Martin75
  • 41
  • 3
  • As a solution, I also tried this way to create the prebuilt shared lib. LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := mylibssl LOCAL_SRC_FILES := libssl.so include $(PREBUILT_SHARED_LIBRARY) But for this, (when My App/mylibssl/Android.mk is called), I receive the message that: make: Nothing to be done for `all_modules'. and so the prebuilt lib is not created. – Martin75 Jan 10 '14 at 08:57
  • 1
    On further debugging, I noticed that under the intermediates directory, only export_includes is created and there is no .so file. This is why we get error: undefined reference to 'BIO_new_mem_buf'. But why does this Android.mk file generate only export_includes!? – Martin75 Jan 10 '14 at 09:11
  • 1
    Why has the question been downvoted? This was my first question. Anything wrong? – Martin75 Jan 10 '14 at 09:19
  • "Why has the question been downvoted?" - just guessing, but it was probably due to lack of formatting. – jww Jan 12 '14 at 02:31
  • "I have spent several hours trying to figure out and am totally stuck." - github has lots of projects that build OpenSSL under the NDK Build system. It should be about as hard as copy/paste: [openssl android site:github.com](https://www.google.com/#q=openssl+android+site:github.com). – jww Jan 12 '14 at 02:33

1 Answers1

0

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.

jww
  • 97,681
  • 90
  • 411
  • 885