Android NDK and OpenSSL build

2,120 views
Skip to first unread message

Vladislav Lozitskyi

unread,
Jul 5, 2017, 10:02:31 AM7/5/17
to android-ndk
Hello! I faced with a strange problem for me: I can not build OpenSSL library for Android.
Every time when I try to build OpenSSL, I get this errors for all *.o files that use stderr, stdin, stdout on linckage step:
undefined reference to 'stderr'
undefined reference to 'stdin'
undefined reference to 'stdout'

This happens on NDKr14 and NDKr15, but on lower versions of NDK OpenSSL library is compiled correctly. Errors appear only for stderr, stdin, stdout and that is strange.

What can I do to build it on the last version of NDK (maybe something broken in NDK?=))? Thanks in advance.

My build script for OpenSSL library (works on NDKr13 and lower):
if [ -z "$ANDROID_NDK" ]; then
    echo
"ANDROID_NDK is not definied. Please, point ANDROID_NDK variable."
   
exit 0
fi


if [ -z "$1" ]; then
    echo
"Usage:"
    echo
"$0 arm64"
    echo
"$0 armv7a"
    echo
"$0 x86"
    echo
"$0 x86_64"
   
exit 0
fi


ARCH
=$1
TOOLCHAIN_DIR
="$(pwd)/toolchain"
PREFIX
="$(pwd)/build"
CROSS_SYSROOT
="$TOOLCHAIN_DIR/sysroot"
CFLAGS
="-funroll-loops -ffast-math -O3 -fPIC"


if [ "$ARCH" == "armv7a" ]; then
    echo
"Chosen arch: armv7a"
    CROSS_PREFIX
="$TOOLCHAIN_DIR/bin/arm-linux-androideabi-"
    TARGET
="android-armv7"
    CFLAGS
="$CFLAGS -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -mthumb"
   
if [ -f "$TOOLCHAIN_DIR/touch" ]; then
        echo
"Using existing toolchain..."
   
else
        echo
"Make standalone toolchain..."
        rm
-rf $TOOLCHAIN_DIR
        $ANDROID_NDK
/build/tools/make-standalone-toolchain.sh \
               
--toolchain=arm-linux-androideabi-4.9 \
               
--platform=android-15 \
               
--install-dir=$TOOLCHAIN_DIR
        touch $TOOLCHAIN_DIR
/touch
   
fi
elif [ "$ARCH" == "arm64" ]; then
    echo
"Chosen arch: arm64"
    CROSS_PREFIX
="$TOOLCHAIN_DIR/bin/aarch64-linux-android-"
    TARGET
="linux-aarch64"
   
if [ -f "$TOOLCHAIN_DIR/touch" ]; then
        echo
"Using existing toolchain..."
   
else
        echo
"Make standalone toolchain..."
        rm
-rf $TOOLCHAIN_DIR
        $ANDROID_NDK
/build/tools/make-standalone-toolchain.sh \
               
--toolchain=aarch64-linux-android-4.9 \
               
--platform=android-21 \
               
--install-dir=$TOOLCHAIN_DIR
        touch $TOOLCHAIN_DIR
/touch
   
fi
elif [ "$ARCH" == "x86" ]; then
    echo
"Chosen arch: x86"
    CROSS_PREFIX
="$TOOLCHAIN_DIR/bin/i686-linux-android-"
    TARGET
="android-x86"
    CFLAGS
="$CFLAGS -march=atom -msse3 -mfpmath=sse"
   
if [ -f "$TOOLCHAIN_DIR/touch" ]; then
        echo
"Using existing toolchain..."
   
else
        echo
"Make standalone toolchain..."
        rm
-rf $TOOLCHAIN_DIR
        $ANDROID_NDK
/build/tools/make-standalone-toolchain.sh \
               
--toolchain=x86-4.9 \
               
--platform=android-16 \
               
--install-dir=$TOOLCHAIN_DIR
        touch $TOOLCHAIN_DIR
/touch
   
fi
elif [ "$ARCH" == "x86_64" ]; then
    echo
"Chosen arch: x86_64"
    CROSS_PREFIX
="$TOOLCHAIN_DIR/bin/x86_64-linux-android-"
    TARGET
="linux-x86_64"
   
if [ -f "$TOOLCHAIN_DIR/touch" ]; then
        echo
"Using existing toolchain..."
   
else
        echo
"Make standalone toolchain..."
        rm
-rf $TOOLCHAIN_DIR
        $ANDROID_NDK
/build/tools/make-standalone-toolchain.sh \
               
--toolchain=x86_64-4.9 \
               
--platform=android-21 \
               
--install-dir=$TOOLCHAIN_DIR
        touch $TOOLCHAIN_DIR
/touch
   
fi
else
    echo
"Unknown arch: $ARCH"
   
exit 0
fi


# echo "Cleaning..."
# make clean
# rm -rf $PREFIX


echo
"Configurating..."
./Configure \
       
--prefix=$PREFIX \
       
--openssldir=$PREFIX \
       
--cross-compile-prefix=$CROSS_PREFIX \
        zlib
-dynamic \
       
no-shared \
        $TARGET
\
    $CFLAGS


echo
"Compiling..."
make depend
make
-j8
make install


echo
"Done!"


Andrew Esh

unread,
Jul 6, 2017, 1:18:46 PM7/6/17
to android-ndk
I don't see what's wrong with what you are doing. I use shared libraries instead of no-shared, like you are. I build openssl-1.0.2k with NDK r15 for the Pixel C like this:

  # Pixel C/dragon/ryu
  export ANDROID_HOME=$HOME/android-sdk
  export ANDROID_NDK_ROOT=$HOME/android-ndk-r15
  export ANDROID_NDK_API=26
  export ANDROID_NDK_ARCH=arm64
  export ANDROID_NDK_HOST=aarch64-linux-android
  export ANDROID_NDK_ABI=arm64-v8a

echo "Checking for Android Standalone NDK..."
if [ ! -e $ANDROID_NDK_ROOT-$ANDROID_NDK_ARCH-$ANDROID_NDK_API ]; then
  echo "Creating the Android Standalone NDK..."
  if [ ! -e $ANDROID_NDK_ROOT ]; then
    echo "The NDK directory $ANDROID_NDK_ROOT does not exist, aborting!"
    exit 1
  fi
  $ANDROID_NDK_ROOT/build/tools/make_standalone_toolchain.py --arch=$ANDROID_NDK_ARCH --api=$ANDROID_NDK_API --install-dir=$ANDROID_NDK_ROOT-$ANDROID_NDK_ARCH-$ANDROID_NDK_API --stl=libc++
fi

EXTRA=`pwd`
SOURCE=$EXTRA/source
AUTOTOOLS=$EXTRA/data/autotools
PATCHES=$EXTRA/patches
SYSROOT=$EXTRA/sysroot
DOWNLOAD=$EXTRA/download
JNILIBS=$EXTRA/jniLibs/$ANDROID_NDK_ABI
SHARED_LIB=`find $ANDROID_NDK_ROOT-$ANDROID_NDK_ARCH-$ANDROID_NDK_API -name "*shared.so" | head -1`
mkdir -p $SOURCE $SYSROOT $DOWNLOAD $JNILIBS
echo "Copying shared library to jniLibs..."
cp -f $SHARED_LIB $JNILIBS

echo "Checking for openssl..."
OPENSSL_VERSION=1_0_2k
if [ ! -e $SYSROOT/lib/libqdassl.so ] || [ ! -e $SYSROOT/lib/libqdacrypto.so ] || [ ! -e $SYSROOT/include/openssl ]; then
  if [ ! -e $SOURCE/openssl-OpenSSL_$OPENSSL_VERSION ]; then
    echo "Building openssl..."
    if [ ! -e $DOWNLOAD/OpenSSL_$OPENSSL_VERSION.tar.gz ]; then
      echo "Downloading openssl..."
      pushd $DOWNLOAD
      popd
    fi
    pushd $SOURCE
    tar -xvf $DOWNLOAD/OpenSSL_$OPENSSL_VERSION.tar.gz
    popd
    if [ "$ANDROID_NDK_ARCH" == "x86" ]; then
      export MACHINE=i686
    else
        if [ "$ANDROID_NDK_ARCH" == "arm64" -o "$ANDROID_NDK_ARCH" == "aarch64" ]; then
            export MACHINE=aarch64
        else
            export MACHINE=armv7
        fi
    fi
    export ARCH=$ANDROID_NDK_ARCH
    export CROSS_COMPILE=$ANDROID_NDK_HOST-
    export SYSTEM=android
    export ANDROID_DEV=$ANDROID_NDK_ROOT-$ANDROID_NDK_ARCH-$ANDROID_NDK_API/sysroot/usr
    pushd $SOURCE/openssl-OpenSSL_$OPENSSL_VERSION
    if [ "$ANDROID_NDK_ARCH" == "arm64" -o "$ANDROID_NDK_ARCH" == "aarch64" ]; then
        patch < $PATCHES/openssl-config.patch
        patch < $PATCHES/openssl-Configure.patch
    fi
    ./config shared no-ssl2 no-ssl3 no-comp no-hw no-engine no-dso no-asm --prefix=$SYSROOT --openssldir=$SYSROOT
    patch < $PATCHES/openssl-Makefiles.patch
    make clean
    make depend
    make CALC_VERSIONS="SHLIB_COMPAT=; SHLIB_SOVER=" MAKE="make -e" all
    popd
  fi
  echo "Installing openssl..."
  mkdir -p $SYSROOT/lib
  pushd $SOURCE/openssl-OpenSSL_$OPENSSL_VERSION
  echo "place-holder make target for avoiding symlinks" >> $SYSROOT/lib/link-shared
  make SHLIB_EXT=.so install_sw
  rm $SYSROOT/lib/link-shared
  pushd $SYSROOT/lib
  ln -s libqdacrypto.so libcrypto.so
  ln -s libqdassl.so libssl.so
  popd
  popd
fi

Patches:

--- config 2017-01-26 07:22:36.000000000 -0600
+++ /home/andrewes/openssl_mods/config 2017-05-08 10:08:02.275587001 -0500
@@ -862,6 +862,7 @@
   *-*-qnx6) OUT="QNX6" ;;
   x86-*-android|i?86-*-android) OUT="android-x86" ;;
   armv[7-9]*-*-android) OUT="android-armv7" ;;
+  aarch64-*-android) OUT="android-aarch64" ;;
   *) OUT=`echo $GUESSOS | awk -F- '{print $3}'`;;
 esac
 

--- Configure 2017-01-26 07:22:36.000000000 -0600
+++ /home/andrewes/openssl_mods/Configure 2017-05-09 11:16:17.585722000 -0500
@@ -474,6 +474,7 @@
 "android","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "android-x86","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:".eval{my $asm=${x86_elf_asm};$asm=~s/:elf/:android/;$asm}.":dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"android-aarch64","clang:-I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${aarch64_asm}:linux64:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "android-mips","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 
 #### *BSD [do see comment about ${BSDthreads} above!]

Dan Albert

unread,
Jul 11, 2017, 12:00:13 AM7/11/17
to android-ndk
Standalone toolchains do not work with GCC out of the box: https://github.com/android-ndk/ndk/wiki/Changelog-r14#wont-fix

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk+unsubscribe@googlegroups.com.
To post to this group, send email to andro...@googlegroups.com.
Visit this group at https://groups.google.com/group/android-ndk.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/17bb9874-6569-4c44-adc8-820798d703b4%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages