How to compile libcurl.so with ssl support for android jni

1. download and setup NDK 

… nothing difficult here

2.make stand alone toolchain with Android NDK

command:



export $NDKROOT=file-path-to-NDK-root

$NDKROOT/build/tools/make-standalone-toochain.sh –platform=android-17 –install-dir=/tmp/my-ndk-toolchain –arch=arm

3. setup some env parameters

commands:



export PATH=$PATH:/tmp/my-ndk-toolchain/bin

export LDFLAGS="-L/tmp/my-ndk-toolchain/sysroot/usr/lib"

export CPPFLAGS="-I/tmp/my-ndk-toolchain/sysroot/usr/include/"

(please note that NO SPACES exists between -L and /tmp, also, between -I and /tmp)

4. compile openssl for android

download openssl for android source code and compile.

commands:



mkdir dir_openssl_android

cd dir_openssl_android

git clone https://github.com/guardianproject/openssl-android.git

mv openssl-android jni

cd jni

ndk-build

 

Then copy libssl.so and libcrypto.so into /tmp/my-ndk-toolchain/sysroot/usr/lib/

and copy include/* into /tmp/my-ndk-toolchain/sysroot/include/

 

5. configure command

download curl source files from http://curl.haxx.se/download.html.

Untar the source file and move the rootDir to be jni .

 

#in some dir such as /home/u/programs/ndk/android-ndk-r10d/samples/
mkdir curl_4
cd cur_4
#download curl source 
wget http://curl.haxx.se/download/curl-7.41.0.tar.gz
tar xvf curl-7*
rm *.tar.gz
mv curl-7* jni
cd jni

./configure --host=arm-linux-androideabi \
--with-ssl \
--disable-ftp \
--disable-gopher \
--disable-file \
--disable-imap \
--disable-ldap \
--disable-ldaps \
--disable-pop3 \
--disable-proxy \
--disable-rtsp \
--disable-smtp \
--disable-telnet \
--disable-tftp \
--without-gnutls \
--without-libidn \
--without-librtmp \
--disable-dict

(Select options carefully. for example, if you want proxy function supported by libcurl, the “–disable-proxy \” line should be deleted.)

End of the output should be like this:

……

configure: amending tests/server/Makefile
configure: amending tests/libtest/Makefile
configure: amending docs/examples/Makefile
configure: Configured to build curl/libcurl:

curl version: 7.41.0
Host setup: arm-unknown-linux-androideabi
Install prefix: /usr/local
Compiler: arm-linux-androideabi-gcc
SSL support: enabled (OpenSSL)
SSH support: no (–with-libssh2)
zlib support: enabled
GSS-API support: no (–with-gssapi)
TLS-SRP support: no (–enable-tls-srp)
resolver: default (–enable-ares / –enable-threaded-resolver)
IPv6 support: no (–enable-ipv6)
Unix sockets support: enabled
IDN support: no (–with-{libidn,winidn})
Build libcurl: Shared=yes, Static=yes
Built-in manual: enabled
–libcurl option: enabled (–disable-libcurl-option)
Verbose errors: enabled (–disable-verbose)
SSPI support: no (–enable-sspi)
ca cert bundle: no
ca cert path: no
LDAP support: no (–enable-ldap / –with-ldap-lib / –with-lber-lib)
LDAPS support: no (–enable-ldaps)
RTSP support: no (–enable-rtsp)
RTMP support: no (–with-librtmp)
metalink support: no (–with-libmetalink)
HTTP2 support: disabled (–with-nghttp2)
Protocols: HTTP HTTPS SMB SMBS

SONAME bump: yes – WARNING: this library will be built with the SONAME
number bumped due to (a detected) ABI breakage.
See lib/README.curl_off_t for details on this.

And then


make
 
Then end of output should be like this:

rtoofft.o ../lib/curl-rawstr.o ../lib/curl-nonblock.o ../lib/curl-warnless.o ../lib/libcurl.la -lz
libtool: link: arm-linux-androideabi-gcc -O2 -Wno-system-headers -o .libs/curl curl-tool_binmode.o curl-tool_bname.o curl-tool_cb_dbg.o curl-tool_cb_hdr.o curl-tool_cb_prg.o curl-tool_cb_rea.o curl-tool_cb_see.o curl-tool_cb_wrt.o curl-tool_cfgable.o curl-tool_convert.o curl-tool_dirhie.o curl-tool_doswin.o curl-tool_easysrc.o curl-tool_formparse.o curl-tool_getparam.o curl-tool_getpass.o curl-tool_help.o curl-tool_helpers.o curl-tool_homedir.o curl-tool_hugehelp.o curl-tool_libinfo.o curl-tool_main.o curl-tool_metalink.o curl-tool_mfiles.o curl-tool_msgs.o curl-tool_operate.o curl-tool_operhlp.o curl-tool_panykey.o curl-tool_paramhlp.o curl-tool_parsecfg.o curl-tool_strdup.o curl-tool_setopt.o curl-tool_sleep.o curl-tool_urlglob.o curl-tool_util.o curl-tool_vms.o curl-tool_writeenv.o curl-tool_writeout.o curl-tool_xattr.o ../lib/curl-strtoofft.o ../lib/curl-rawstr.o ../lib/curl-nonblock.o ../lib/curl-warnless.o -L/home/u/programs/ndk/android-ndk-r10d/my_android_toolchain/sysroot/user/lib ../lib/.libs/libcurl.so -lz
make[2]: Leaving directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/src’
make[1]: Leaving directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/src’
Making all in include
make[1]: Entering directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/include’
Making all in curl
make[2]: Entering directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/include/curl’
make all-am
make[3]: Entering directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/include/curl’
make[3]: Leaving directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/include/curl’
make[2]: Leaving directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/include/curl’
make[2]: Entering directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/include’
make[2]: Nothing to be done for `all-am’.
make[2]: Leaving directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/include’
make[1]: Leaving directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/include’
make[1]: Entering directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni’
make[1]: Nothing to be done for `all-am’.
make[1]: Leaving directory `/home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni’

This means no error occurs. 

And the shared library libcurl.so can be found in the dir : ./lib/.libs/libcurl.so (This is a soft link file pointing to the real so file)

 

Now, we have gotten a libcurl.so file.

But… But, When this libcurl.so is being used in your android jni projects. Errors something like “libcurl.so.5 could not found ” error. Because, the file name of generated libcurl.so is libcurl.so.5 exactly. With ending with “.5”, the file could not be used as jni library. Because, libraries used in Android jni are expected ending with “.so” only.

 

So, we should figure out a way to generate an libcurl.so whose file name is libcurl.so!

Steps continues..

6. Modify Android.mk file of curl project

copy packages/Android/Android.mk into /home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/

Modify the file to be :


#-------------------------begin Android.mk------------------------------------------------------------------------

LOCAL_PATH:= $(call my-dir)

common_CFLAGS := -Wpointer-arith -Wwrite-strings -Wunused -Winline -Wnested-externs -Wmissing-declarations -Wmissing-prototypes -Wno-long-long -Wfloat-equal -Wno-multichar -Wsign-compare -Wno-format-nonliteral -Wendif-labels -Wstrict-prototypes -Wdeclaration-after-statement -Wno-system-headers -DHAVE_CONFIG_H

#########################
# Build the libcurl library

include $(CLEAR_VARS)
include $(LOCAL_PATH)/lib/Makefile.inc
CURL_HEADERS := \
curlbuild.h \
curl.h \
curlrules.h \
curlver.h \
easy.h \
mprintf.h \
multi.h \
stdcheaders.h \
typecheck-gcc.h

OPENSSL_ROOT := /home/u/programs/openssl/openssl_android/jni/

LOCAL_SRC_FILES := $(addprefix lib/,$(CSOURCES))
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include/ $(OPENSSL_ROOT)/include/ $(LOCAL_PATH)/lib
LOCAL_CFLAGS += $(common_CFLAGS)

LOCAL_COPY_HEADERS_TO := libcurl/curl
LOCAL_COPY_HEADERS := $(addprefix include/curl/,$(CURL_HEADERS))

LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -lssl -lcrypto -lz
LOCAL_MODULE:= libcurl
LOCAL_MODULE_TAGS := optional

# Copy the licence to a place where Android will find it.
# Actually, this doesn't quite work because the build system searches
# for NOTICE files before it gets to this point, so it will only be seen
# on subsequent builds.
ALL_PREBUILT += $(LOCAL_PATH)/NOTICE
$(LOCAL_PATH)/NOTICE: $(LOCAL_PATH)/COPYING | $(ACP)
$(copy-file-to-target)

include $(BUILD_SHARED_LIBRARY)

#delete original lines from here to the end ..

#-------------------------end Android.mk------------------------------------------------------------------------

The modification lines are in bold.

Then,

 


export SYSROOT=/tmp/my-ndk-toolchain/sysroot

And run:



ndk-build

 

libcurl.so could be found in ../libs/armeabi/libcurl.so

 

继续阅读“How to compile libcurl.so with ssl support for android jni”

编译android版本openssl共享库

1. 从https://github.com/guardianproject/openssl-android下载Openssl for android源代码

git clone https://github.com/guardianproject/openssl-android.git

2. 改名源代码的目录为jni

mv openssl-android jni

因为jni项目的Android.mk只有在jni目录中才能执行ndk-build命令否则会报错

当时的目录结构应该是这样的:

u@u:~/programs/openssl/openssl_android$ tree jni -L 1
jni
├── android-config.mk
├── AndroidManifest.xml
├── Android.mk
├── android.testssl
├── apps
├── CleanSpec.mk
├── crypto
├── default.properties
├── e_os2.h
├── e_os.h
├── import_openssl.sh
├── include
├── jni
├── libs
├── MODULE_LICENSE_BSD_LIKE
├── NOTICE
├── obj
├── openssl-android
├── openssl.config
├── openssl.version
├── patches
├── README.android
├── README.txt
├── ssl
└── ThirdPartyProject.prop

在jni目录中执行命令ndk-build,没有错误生成四个文件分别如下:

u@u:~/programs/openssl/openssl_android/jni$ ls -l libs/armeabi/
total 1380
-rwxr-xr-x 1 u u 857984 Mar 29 14:57 libcrypto.so
-rwxr-xr-x 1 u u 201472 Mar 29 14:57 libssl.so
-rwxr-xr-x 1 u u 304536 Mar 29 14:57 openssl
-rwxr-xr-x 1 u u 38664 Mar 29 14:57 ssltest