Build OpenSSL for Qt Android

OpenSSL is not bundled on Android anymore and when using Qt on Android you need to supply your own copies of libssl.so and libcrypto.so in case you need to use any secure networking functions, like https connections.  The instructions at Qt are unclear on NDK and OpenSSL versions and the instructions only work with older versions of the Android NDK. This article will clear up that confusions and explain how to build OpenSSL so that secure networking can be used in your Qt Android projects.

We will assume that you otherwise have an working Android SDK & NDK environment with Qt for Android installed!

Create custom toolchains

In NDK 18 you need to create a custom native toolchain so that all paths and things point to the correct files. Choose a suitable Android platform version and architecture (arm,arm64,x86,x86_64) according to your project needs.

Create a 32-bit ARM toolchain

This will build a 32-bit ARM toolchain for platform level 19, Android 4.4

$NDK/build/tools/make_standalone_toolchain.py --arch arm --api 19 --install-dir /opt/android-19-arm

Create a 64-bit ARM toolchain

This will build a 64-bit ARM toolchain for platform level 21, the first to support 64-bit ARM, Android 5.0

$NDK/build/tools/make_standalone_toolchain.py --arch arm64 --api 21 --install-dir /opt/android-21-arm64

Qt 5.12.4 and later, using OpenSSL 1.1.1

Qt 5.12.4 and later have moved to OpenSSL 1.1.1 and can not be used anymore with OpenSSL 1.0.2. If you are using 5.12.4 or a later version, follow these instructions.

Download OpenSSL 1.1.1c

Next, download OpenSSL source archive from the 1.1.1 series, latest at time of writing was 1.1.1c (Always use the latest version!):

wget https://www.openssl.org/source/openssl-1.1.1c.tar.gz

Check source archive checksum:

wget https://www.openssl.org/source/openssl-1.1.1c.tar.gz.sha256
sha256sum openssl-1.0.2q.tar.gz

And compare output with the contents of openssl-1.1.1.tar.gz.sha256

Extract the source archive:

tar xf openssl-1.1.1c.tar.gz

And go into the source directory:

cd openssl-1.1.1c

Configure and build (adjust PATHs according to the toolchain you use)

32-bit ARM

PATH=/opt/android-19-arm/bin:$PATH ANDROID_NDK_HOME=/opt/android-19-arm/ CROSS_COMPILE=/opt/android-19-arm/bin/arm-linux-androideabi- ./Configure android-arm shared
PATH=/opt/android-19-arm/bin:$PATH ANDROID_NDK_HOME=/opt/android-19-arm/ CROSS_COMPILE=/opt/android-19-arm/bin/arm-linux-androideabi- make

64-bit ARM

PATH=/opt/android-21-arm64/bin:$PATH ANDROID_NDK_HOME=/opt/android-21-arm64/ CROSS_COMPILE=/opt/android-21-arm64/bin/aarch64-linux-androideabi- ./Configure android-arm64 shared
PATH=/opt/android-21-arm64/bin:$PATH ANDROID_NDK_HOME=/opt/android-21-arm64/ CROSS_COMPILE=/opt/android-21-arm64/bin/aarch64-linux-androideabi- make

Qt 5.12.3 and older, using OpenSSL 1.0.2

For Qt 5.12.3 and older you need to use OpenSSL 1.0.2 series.

Prepare OpenSSL 1.0.2q

Next, download OpenSSL source archive from the 1.0.2 series, latest at time of writing was 1.0.2s (Always use the latest version!):
wget https://www.openssl.org/source/openssl-1.0.2s.tar.gz

Check source archive checksum:

wget https://www.openssl.org/source/openssl-1.0.2s.tar.gz.sha256
sha256sum openssl-1.0.2s.tar.gz

And compare the output with the contents of openssl-1.0.2s.tar.gz.sha256.

Extract the source archive:

tar xf openssl-1.0.2s.tar.gz

And go into the source directory:

cd openssl-1.0.2s

Fix for clang toolchain

OpenSSL configure assumes that the C compile is gcc and sets the "-mandroid" flag. Android NDK is using clang now so we need to remove it first. Run:

sed -i -e 's/-mandroid//' Configure

Configure and build OpenSSL for Android

Choose one of the toolchain that you prepared above and configure and build OpenSSL with it

CROSS_COMPILE=/opt/android-19-arm/bin/arm-linux-androideabi- ./Configure android shared
make ANDROID_DEV=/opt/android-19-arm/sysroot/usr/ CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" build_libs

For 64-bit ARM build

CROSS_COMPILE=/opt/android-21-arm64/bin/aarch64-linux-android- ./Configure android shared
make ANDROID_DEV=/opt/android-21-arm64/sysroot/usr CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" build_libs

Verify the libraries are built for correct arch

file libssl.so libcrypto.so

Should respond with the following for 32-bit ARM

libssl.so:    ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, not stripped
libcrypto.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, not stripped

And for 64-bit ARM with

libssl.so:    ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, not stripped
libcrypto.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, not stripped

Add to libraries your Qt Android project

Copy libssl.so libcrypto.so to your project, for example in PROJECT-ROOT/3rdparty/openssl-armv7/

And add the reference to your Qt project file:

contains(ANDROID_TARGET_ARCH,armeabi-v7a) {
    ANDROID_EXTRA_LIBS = \
        $$PWD/3rdparty/openssl-armv7/libcrypto.so \
        $$PWD/3rdparty/openssl-armv7/libssl.so
}

Or use the Qt Creator UI to add the libraries to your project.