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

 

if you got errors like this :

/bin/ld: error: cannot find -lssl

/bin/ld: error: cannot find -lcrypto

The follow actions maybe help :

 


cd /home/u/programs/ndk/android-ndk-r10d/samples/curl_4/jni/
mkdir prebuilt

#cp libssl.so and libcrypto.so (arm version compiled in former steps) into prebuilt

cp /home/u/programs/openssl/openssl_android/jni/libs/armeabi/*.so prebuilt/


Then, modify Android.mk file specifying the location of libssl.so and libcrypto.so

u@u:~/programs/ndk/android-ndk-r10d/samples/curl_3/jni$ tree prebuilt/
prebuilt/
├── Android.mk
├── libcrypto.so
└── libssl.so

the content of prebuilt/Android.mk :

u@u:~/programs/ndk/android-ndk-r10d/samples/curl_3/jni$ cat prebuilt/Android.mk


LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := libssl.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := libcrypto.so
include $(PREBUILT_SHARED_LIBRARY)

And the content of Android.mk is like this:
u@u:~/programs/ndk/android-ndk-r10d/samples/curl_3/jni$ cat 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_SHARED_LIBRARIES += libssl libcrypto
#LOCAL_LDLIBS   += -L$(SYSROOT)/usr/lib -lssl -lcrypto -lz
LOCAL_LDLIBS   += -L$(SYSROOT)/usr/lib -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)
include $(LOCAL_PATH)/prebuilt/Android.mk 

then :

ndk-build

Should success.

If any questions, feel free contact me . 

All steps told above were tested successfully by me several times. 

 

Refer: https://kexiao8.com/blog/index.php/2014/05/12/75.html

“How to compile libcurl.so with ssl support for android jni”的9个回复

  1. 你好!我已經成功產生出libcurl,但我是用指令的方式去執行c檔,指令如下 arm-linux-androideabi-gcc curl.c -o curl.bin -lcurl -I”curl/incldue/” -L”curl/lib”,然後我將bin執行檔 push到android 手機,並且執行,但出現了link_image[1941]: 12678 could not load needed library ‘libcurl.so.5’ for ‘./curl.bin’ (load_library[1096]: Library ‘libcurl.so.5’ not found)CANNOT LINK EXECUTABLE 這個錯誤訊息,想請問是什麼原因呢?感謝你!

  2. 你好,我链接的时候出现以下问题,你遇到过么?

    jni/lib/vtls/openssl.c:1947: error: undefined reference to ‘SSL_CTX_set_srp_username’
    jni/lib/vtls/openssl.c:1951: error: undefined reference to ‘SSL_CTX_set_srp_password’

    1. 没有..貌似你使用到了SSL_CTX_set_srp_username 这两个变量?这两个变量没有找到定义。你可以到源代码里面搜一下,哪里用到了,为什么链接的时候反而提示找不到。

  3. 你好,我运行完make-standalone-toolchain.sh –arch=arm –platform=android-17 –install-dir=/tmp/my-ndk-toolchain 后,就已经有 libssl.so and libcrypto.so 在“/tmp/my-ndk-toolchain/sysroot/usr/lib/” 下了。你出现过这样的情况么?

  4. Thanks for sharing experiments, it’s really helpful for me.
    However, could you tell people how to compile the libcurl.a?
    And, could you share the files of libcurl.so and libcurl.a directly and tell people how to use them in Android project? It would save 10k words. 🙂

  5. 你好,我用cygwin编译,出了很多问题。用手机里编译好的libcurl.so放到别人机子上会有strchr_chk找不到的错。我想问是不是自己编的这个库在其他android上会有依赖找不到的函数等其他现象。libcurl.so在android下是否稳定?或者我去多找几个这样的库去实验下?谢谢

发表评论

电子邮件地址不会被公开。 必填项已用*标注