Compile openssl and curl for Android
For anyone that only wants pre-compiled static libraries of openssl and curl, check out this repo robertying/openssl-curl-android and its releases.
The way of compiling the libs have been drastically changed since I wrote this post. The following only serves as a demonstration of ideas. Please refer to robertying/openssl-curl-android for the latest working scripts.
Compiling openssl and curl can be a natural request if you are integrating some C libraries into your Android project. Android use four ABIs that are not compatible with modern desktop environments, so we will have to
cross-compile those libraries to be able to run them on mobile devices.
Cross-compilation is generally easy if we get the right
cross-compiler do we have for Android? It is included in
NDK! Once you have NDK installed, you will find corresponding cross-compilers inside its bundle.
For macOS users, it will be located in
$ANDROID_NDK_HOME is the
ndk-bundle path and
$HOST_TAG is the identifier for your OS. Find your
$HOST_TAG in Android NDK docs.
Autotool based build system
We can build some simple C files together with the cross compiler. However, openssl and curl are both complex and large projects using a GNU-autotools-like build system. This means we still need to use their own build system and we need to rightly configure so the final binary is built for Android ABIs.
curl needs a SSL library so we will build openssl first.
We can find build instructions on its repo. It is pretty in detail. Simply follow the instructions and you shall be able to compile the library.
Here is one of my scripts:
# You need to set `$MIN_SDK_VERSION`, `$ANDROID_NDK_HOME` and `$HOST_TAG` firstexport TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$HOST_TAGPATH=$TOOLCHAIN/bin:$PATH./Configure android-arm64 no-shared \-D__ANDROID_API__=$MIN_SDK_VERSION \--prefix=$PWD/build/arm64-v8a
Just a few caveats:
llvmseems better if you are compiling on macOS, so put
PATH. Then autotools can use the right compiler for the job.
- The corresponding arguments for four ABIs are
- You can add
Configureif a static library is wanted.
- Pay attention how
./Configureis called -- there is no dash or option name.
--prefixbecause we do not want the library to be installed on the system which is default.
Configure, autotools will generate correct Makefiles for the ABI.
You will see all
For a full script, see build-openssl.sh
curl does not use
Configure for Makefile generations but a similar one named
Before all, we first need to generate a special header file to proceed with the building.
curl directory, or you will get a
not found error for
curl_config.h because it is generated by
buildconf. Just run it for a relatively short time and kill the process,
curl_config.h will be available.
curl is a little trickier than with
openssl. We need to declare all cross-compiling tools first to make it work.
For example, to compile against
arm64 ABI, we need to first export the following environment variables:
# arm64export TARGET_HOST=aarch64-linux-androidexport TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/$HOST_TAGPATH=$TOOLCHAIN/bin:$PATHexport AR=$TOOLCHAIN/bin/$TARGET_HOST-arexport AS=$TOOLCHAIN/bin/$TARGET_HOST-asexport CC=$TOOLCHAIN/bin/$TARGET_HOST$MIN_SDK_VERSION-clangexport CXX=$TOOLCHAIN/bin/$TARGET_HOST$MIN_SDK_VERSION-clang++export LD=$TOOLCHAIN/bin/$TARGET_HOST-ldexport RANLIB=$TOOLCHAIN/bin/$TARGET_HOST-ranlibexport STRIP=$TOOLCHAIN/bin/$TARGET_HOST-stripexport SSL_DIR=$PWD/../openssl/build/arm64-v8a
SSL_DIR is for locating
openssl if we want to use
Then we have the standard autotools' way:
./configure --host=$TARGET_HOST \--target=$TARGET_HOST \--prefix=$PWD/build/arm64-v8a \--with-ssl=$SSL_DIR \--disable-shared
Here we only compiled static ones. Building shared libraries with some ARM ABI may cause problems. It may be a bug with NDK toolchains so I recommend sticking to static ones.
You can continue adding more options to disable functions, reducing the library size.
Find all stuff in
For a full script, see build-curl.sh
You can also combine all the environment variable setup in shell scripts. See my-build.sh for example.