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
你好!我已經成功產生出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 這個錯誤訊息,想請問是什麼原因呢?感謝你!
请看完整篇文章啊,兄台。本文的后面一部分就解释了这种问题出现的原因和解决方法的。
你好,我链接的时候出现以下问题,你遇到过么?
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’
没有..貌似你使用到了SSL_CTX_set_srp_username 这两个变量?这两个变量没有找到定义。你可以到源代码里面搜一下,哪里用到了,为什么链接的时候反而提示找不到。
你好,我运行完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/” 下了。你出现过这样的情况么?
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. 🙂
That’s my pleasure to be help. And also, I’ll consider your proposals, It’s a great idea I think.
你好,我用cygwin编译,出了很多问题。用手机里编译好的libcurl.so放到别人机子上会有strchr_chk找不到的错。我想问是不是自己编的这个库在其他android上会有依赖找不到的函数等其他现象。libcurl.so在android下是否稳定?或者我去多找几个这样的库去实验下?谢谢
你好。很稳定的。