My attempt to build OpenSSL for Android on Windows

I tried to build OpenSSL for Android with the following commands in Windows Command Prompt:

cd C:\dev\repos\openssl-1.1.1r

set MY_NDK_DIR=C:\Users\dmitr\AppData\Local\Android\Sdk\ndk\23.1.7779620

set MY_CLANG_DIR=%MY_NDK_DIR%\toolchains\llvm\prebuilt\windows-x86_64\bin
set MY_CMAKE=%MY_NDK_DIR%\prebuilt\windows-x86_64\bin\make.exe
set MY_PERL_DIR=C:\dev\PFiles\Strawberry\perl\bin

set PATH=%MY_CLANG_DIR%;%MY_PERL_DIR%;%PATH%

set "MY_ANDROID_BUILD_ABI=x86_64"
rem set "MY_ANDROID_BUILD_ABI=x86"
rem set "MY_ANDROID_BUILD_ABI=arm64"
rem set "MY_ANDROID_BUILD_ABI=arm"

set MY_INSTALL_ROOT_DIR=C:/dev/libs/OpenSSL-android
set MY_INSTALL_DIR=%MY_INSTALL_ROOT_DIR%/%MY_ANDROID_BUILD_ABI%

set ANDROID_NDK_HOME=%MY_NDK_DIR%

# Set compiler clang, instead of gcc by default
set CC=clang

perl Configure android-%MY_ANDROID_BUILD_ABI% -D__ANDROID_API__=23 --prefix="%MY_INSTALL_DIR%" --openssldir="%MY_INSTALL_DIR%" no-shared

But got the following error:

Configuring OpenSSL version 1.1.1r (0x1010112fL) for android-x86_64
Using os-specific seed configuration
no NDK clang on $PATH at (eval 11) line 139.

in C:\dev\repos\openssl-1.1.1r\Configurations\15-android.conf:

            my $triarch = $triplet{$arch};
            my $cflags;
            my $cppflags;

            # see if there is NDK clang on $PATH, "universal" or "standalone"
            if (which("clang") =~ m|^$ndk/.*/prebuilt/([^/]+)/|) {
                my $host=$1;
                # harmonize with gcc default
                my $arm = $ndkver > 16 ? "armv7a" : "armv5te";
                (my $tridefault = $triarch) =~ s/^arm-/$arm-/;
                (my $tritools   = $triarch) =~ s/(?:x|i6)86(_64)?-.*/x86$1/;
                if (length $sysroot) {
                    $cflags .= " -target $tridefault "
                            .  "-gcc-toolchain \$($ndk_var)/toolchains"
                            .  "/$tritools-4.9/prebuilt/$host";
                    $user{CC} = "clang" if ($user{CC} !~ m|clang|);
                } else {
                    $user{CC} = "$tridefault$api-clang";
                }
                $user{CROSS_COMPILE} = undef;
                if (which("llvm-ar") =~ m|^$ndk/.*/prebuilt/([^/]+)/|) {
                    $user{AR} = "llvm-ar";
                    $user{ARFLAGS} = [ "rs" ];
                    $user{RANLIB} = ":";
                }
            } elsif ($is_standalone_toolchain) {
                my $cc = $user{CC} // "clang";
                # One can probably argue that both clang and gcc should be
                # probed, but support for "standalone toolchain" was added
                # *after* announcement that gcc is being phased out, so
                # favouring clang is considered adequate. Those who insist
                # have option to enforce test for gcc with CC=gcc.
                if (which("$triarch-$cc") !~ m|^$ndk|) {
                    die "no NDK $triarch-$cc on \$PATH";
                }
                $user{CC} = $cc;
                $user{CROSS_COMPILE} = "$triarch-";
            } elsif ($user{CC} eq "clang") {
                die "no NDK clang on \$PATH";
            } else {
                if (which("$triarch-gcc") !~ m|^$ndk/.*/prebuilt/([^/]+)/|) {
                    die "no NDK $triarch-gcc on \$PATH";
                }
                $cflags .= " -mandroid";
                $user{CROSS_COMPILE} = "$triarch-";
            }

clang is in PATH, but

perl -e which("clang")

fails with the following error in Windows Command Prompt.

Undefined subroutine &main::which called at -e line 1.

I tried to switch to Bash:

cd /c/dev/repos/openssl-1.1.1r

export MY_NDK_DIR=/c/Users/dmitr/AppData/Local/Android/Sdk/ndk/23.1.7779620

export MY_CLANG_DIR=${MY_NDK_DIR}/toolchains/llvm/prebuilt/windows-x86_64/bin
export MY_CMAKE=${MY_NDK_DIR}/prebuilt/windows-x86_64/bin/make.exe
export MY_PERL_DIR=/c/dev/PFiles/Strawberry/perl/bin

export PATH=${MY_CLANG_DIR}:${MY_PERL_DIR}:${PATH}

export "MY_ANDROID_BUILD_ABI=x86_64"
#export "MY_ANDROID_BUILD_ABI=x86"
#export "MY_ANDROID_BUILD_ABI=arm64"
#export "MY_ANDROID_BUILD_ABI=arm"

export MY_INSTALL_ROOT_DIR=/c/dev/libs/OpenSSL-android
export MY_INSTALL_DIR=${MY_INSTALL_ROOT_DIR}/${MY_ANDROID_BUILD_ABI}

export ANDROID_NDK_HOME=$MY_NDK_DIR

export CC=clang

perl Configure android-${MY_ANDROID_BUILD_ABI} -D__ANDROID_API__=23 --prefix=${MY_INSTALL_DIR} --openssldir=${MY_INSTALL_DIR} no-shared

but got the same error.

and which did not work in Perl’s command line:

perl -e 'which("clang")'
Undefined subroutine &main::which called at -e line 1.

My first program in Perl:

perl -e 'print("Hello World\n");'

I added

print("$ndk\n");
print(which("clang"));

and it displayed this:

C:\Users\dmitr\AppData\Local\Android\Sdk\ndk\20.1.5948944
C:\Users\dmitr\AppData\Local\Android\Sdk\ndk\201~1.594\TOOLCH~1\llvm\prebuilt\WINDOW~1\bin\clang.EXE

in both Windows Command Prompt and Bash, and more than that m|| is testing for forward-slash but which appears to be returning backslashes.

I also added

print $ENV{PATH};

and got:

C:\Users\dmitr\AppData\Local\Android\Sdk\ndk\201~1.594\TOOLCH~1\llvm\prebuilt\WINDOW~1\bin\clang.EXEC:\Users\dmitr\AppData\Local\Android\Sdk\ndk\20.1.5948944\toolchains\llvm\prebuilt\windows-x86_64\bin;C:\dev\PFiles\Strawberry\perl\bin ...

I have an impression that the script adds C:\Users\dmitr\AppData\Local\Android\Sdk\ndk\201~1.594\TOOLCH~1\llvm\prebuilt\WINDOW~1\bin\clang.EXE to the PATH in some wrong way.

The conclusion is that I would probably switch to Linux.

2 Responses to My attempt to build OpenSSL for Android on Windows

  1. dmitriano says:

    https://stackoverflow.com/questions/25292090/building-openssl-for-android-armv7-on-win32
    -no-ssl2 -no-ssl3 -no-comp -no-hw -no-engine

    https://proandroiddev.com/tutorial-compile-openssl-to-1-1-1-for-android-application-87137968fee
    ndkVersion “20.1.5948944”
    # Set compiler clang, instead of gcc by default
    CC=clang

Leave a Reply

Your email address will not be published. Required fields are marked *