First of all, if this repository or content violate any law or rules from the original owner, please let me know
in the GitHub Issue section. I will take down this repository as soon as possible.
- Clone or download this repository and use the pre-build files inside
android-buildfollow How To Use section. If you prefer latest build, please proceed to the following guide. Thank you.
- Clone OpenSSL repository from GitHub: https://github.com/openssl/openssl.git
git clone https://github.com/openssl/openssl.git- Navigate to
opensslfolder that you already cloned and createandroid-build.shshell script file, put below code in and save.-D__ANDROID_API__=21isminSdkVersioncurrently set to 21. You can change base on the project you build for:
#!/bin/bash
# Exit immediately if a command exits with a non-zero status
set -euo pipefail
# Ensure ANDROID_NDK_ROOT is set
if [ -z "${ANDROID_NDK_ROOT:-}" ]; then
echo "Error: ANDROID_NDK_ROOT environment variable is not set."
echo "Please set it to your Android NDK path (e.g. export ANDROID_NDK_ROOT=/path/to/ndk)"
exit 1
fi
# Detect host OS to locate the prebuilt NDK toolchain
HOST_OS=$(uname -s | tr '[:upper:]' '[:lower:]')
case "$HOST_OS" in
darwin)
NDK_HOST="darwin-x86_64"
;;
linux)
NDK_HOST="linux-x86_64"
;;
*)
echo "Error: Unsupported host OS '$HOST_OS'"
exit 1
;;
esac
TOOLCHAIN_BIN="$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$NDK_HOST/bin"
if [ ! -d "$TOOLCHAIN_BIN" ]; then
echo "Error: NDK toolchain bin directory not found at: $TOOLCHAIN_BIN"
exit 1
fi
# Add the NDK toolchain to the PATH so Configure can find the compiler and binutils
export PATH="$TOOLCHAIN_BIN:$PATH"
# Determine the number of CPU cores for parallel make
NUM_CORES=1
if [ "$HOST_OS" = "darwin" ]; then
NUM_CORES=$(sysctl -n hw.ncpu 2>/dev/null || echo 1)
elif [ "$HOST_OS" = "linux" ]; then
NUM_CORES=$(nproc 2>/dev/null || echo 1)
fi
build_one() {
local arch=$1
local abi=$2
echo "=========================================================="
echo "Building OpenSSL for $arch ($abi)"
echo "=========================================================="
# Only clean if a Makefile exists from a previous config
if [ -f Makefile ]; then
make clean
fi
# Optimization compiler flags
# -Os: optimize for size
# -fdata-sections, -ffunction-sections: allow dead code stripping when linking
# -fvisibility=hidden: hide internal symbols to prevent export bloat
# -g0: omit debug symbols to minimize file size
local cflags="-Os -fdata-sections -ffunction-sections -fvisibility=hidden -g0"
# Disable unused, deprecated, insecure, and heavyweight features to optimize size
local disabled_features="no-shared no-asm no-engine no-comp no-tests no-ui-console \
no-legacy no-deprecated no-quic no-filenames \
no-md2 no-md4 no-mdc2 no-rc2 no-rc4 no-rc5 no-idea no-seed no-bf no-cast no-camellia no-whirlpool \
no-des no-dsa no-srp no-scrypt no-argon2 no-ts no-cms no-nextprotoneg no-ocsp \
no-ssl3 no-tls1 no-tls1-method no-tls1_1 no-tls1_1-method no-dtls \
no-aria no-blake2 no-chacha no-poly1305 no-sm2 no-sm3 no-sm4 \
no-ml-dsa no-ml-kem no-lms"
# Configure the build:
# --libdir=lib: Force lib directory name (avoiding lib64 on 64-bit architectures)
# -D__ANDROID_API__=21: Set baseline Android API level 21
./Configure "$arch" \
-D__ANDROID_API__=21 \
--libdir=lib \
$disabled_features \
$cflags \
-fPIC \
--prefix="$(pwd)/android-build/$abi"
# Compile using parallel cores
make -j"$NUM_CORES"
# Install software components only (skips documentation)
make install_sw
# Move static libraries to the top level of the build directory
local dest_dir="$(pwd)/android-build/$abi"
mv "$dest_dir/lib/libssl.a" "$dest_dir/"
mv "$dest_dir/lib/libcrypto.a" "$dest_dir/"
# Strip debugging symbols and unneeded symbols from the static libraries
if command -v llvm-strip >/dev/null 2>&1; then
echo "Stripping static libraries..."
llvm-strip -g "$dest_dir/libssl.a"
llvm-strip -g "$dest_dir/libcrypto.a"
else
echo "Warning: llvm-strip not found. Libraries were not stripped."
fi
# Clean up installation folders to leave only include/ and the static libraries
rm -rf "$dest_dir/bin"
rm -rf "$dest_dir/lib"
rm -rf "$dest_dir/share"
}
# Build for target architectures
build_one "android-arm64" "arm64-v8a"
build_one "android-arm" "armeabi-v7a"
# Optional: uncomment to also build for emulators / x86 targets
# build_one "android-x86_64" "x86_64"
# build_one "android-x86" "x86"
if [ -f Makefile ]; then
make clean
fi
echo "========== ALL DONE =========="- Run below command to grand execute permission to the script file you've just created:
chmod +x build_openssl.sh- Now run the script and wait until it finish. This will take a while depends on your machine performance:
./android-build.sh- When all build complete, you can see folder named
android-buildinside currentopenssldirectory we're working on.
- Copy all the content inside
android-buildfolder and place inside your project'scppfolder. I recommend to put undercpp → libs → opensslfolder so it's easy to copy belowCMakeListwithout making any change. Directory look like this:
cpp/
└── libs/
└── openssl/
├── arm64-v8a/
│ ├── include/
│ │ └── openssl/
│ ├── libcrypto.a
│ └── libssl.a
├── armeabi-v7a/
│ ├── include/
│ │ └── openssl/
│ ├── libcrypto.a
│ └── libssl.a
├── x86/
│ ├── include/
│ │ └── openssl/
│ ├── libcrypto.a
│ └── libssl.a
└── x86_64/
├── include/
│ └── openssl/
├── libcrypto.a
└── libssl.a
├── CMakeLists.txt
└── native-lib.cpp
- Add these below line to your
CMakeLists.txtand make sure it abovetarget_link_libraries. If your main lib is notnative-lib.cppyou can update it according to your project naming:
# OpenSSL Configuration ========================================================
# Hide symbols to prevent conflicts in the final SDK
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
# Path to headers
target_include_directories(native-lib PRIVATE ${CMAKE_SOURCE_DIR}/libs/openssl/${ANDROID_ABI}/include)
# Import libssl
add_library(ssl STATIC IMPORTED)
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/openssl/${ANDROID_ABI}/libssl.a)
# Import libcrypto
add_library(crypto STATIC IMPORTED)
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/openssl/${ANDROID_ABI}/libcrypto.a)
# ==============================================================================
- Finally, add
sslandcryptototarget_link_libraries. Make sure thatsslis beforecryptoand those 2 are at the end oftarget_link_libraries. Here is the example of what it looks like:
target_link_libraries(native-lib PRIVATE ${log-lib} android ssl crypto)
- I'll drop a snipped code to my
CMakeLists.txtto show you what is look like:
cmake_minimum_required(VERSION 3.18.1)
project(CPP-Android-OpenSSL)
add_library(native-lib SHARED native-lib.cpp)
find_library(log-lib log)
# OpenSSL Configuration ========================================================
# Hide symbols to prevent conflicts in the final SDK
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
# Path to headers
target_include_directories(native-lib PRIVATE ${CMAKE_SOURCE_DIR}/libs/openssl/${ANDROID_ABI}/include)
# Import libssl
add_library(ssl STATIC IMPORTED)
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/openssl/${ANDROID_ABI}/libssl.a)
# Import libcrypto
add_library(crypto STATIC IMPORTED)
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libs/openssl/${ANDROID_ABI}/libcrypto.a)
# ==============================================================================
target_link_libraries(native-lib PRIVATE ${log-lib} android ssl crypto)
- The library size is over 50MB and almost 600 items during I make this document. I would suggest you to add the
main
opensslfolder to.gitignoreso you don't push all this files to your repository.