Martin Perry
Martin Perry

Reputation: 9527

Android NDK - static library failed to link

I have a script to build static library for Android. I have used it about a year ago with no problem. However, when I now build a library using the exactly same script, and use it in my project as before, I got many linker errors that look like this:

C:/Users/Perry/AppData/Local/Android/sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin\ld: error: ../../../../../../External_libs_android/libs/icu/jni/x86/libicuuc.a(chariter.ao): relocation R_386_GOTOFF against preemptible symbol _ZTVN3icu17CharacterIteratorE cannot be used when making a shared object

I have not changed anything in my build process since the last year, the only new things are NDK version and Android Studio version.

I have NDK 18.1.5063045

EDIT:

If I switched back to NDK 16, all is working correctly

For Android build of static library, I use this scripts (source: https://github.com/MartinPerry/icu-build-scripts)

prefix.sh

export ICU_VERSION="60-2"

export BASE_ICU_DIR="/Users/perry/Development/icu-cross-compile-master"

export ICU_DIR="${BASE_ICU_DIR}/icu-${ICU_VERSION}"

export ICU_SOURCE="${ICU_DIR}/source"

export PREBUILD="${BASE_ICU_DIR}/scripts/mac/icu_build"

export NDK_STANDALONE_TOOLCHAIN_ROOT="${BASE_ICU_DIR}/scripts/android/toolchains"

export ANDROID_NDK="/Users/perry/Library/Android/sdk/ndk-bundle"

export CONFIG_PREFIX=" --enable-extras=yes \
--enable-tools=yes \
--enable-icuio=yes \
--enable-strict=no \
--enable-static \
--enable-shared=no \
--enable-tests=yes \
--disable-renaming \
--enable-samples=no \
--enable-dyload=no \
--with-data-packaging=static"

export CFLAGS="-O3 -D__STDC_INT64__ -fno-exceptions -fno-short-wchar -fno-short-enums"

export CXXFLAGS="${CFLAGS} -std=c++11"

#will set value to 1
defines_config_set_1=( \
"UCONFIG_NO_COLLATION" \
"UCONFIG_NO_LEGACY_CONVERSION" \
"UCONFIG_NO_BREAK_ITERATION" \
"UCONFIG_NO_COLLATION" \
"UCONFIG_NO_FORMATTING" \
"UCONFIG_NO_REGULAR_EXPRESSIONS" \
"UCONFIG_NO_LEGACY_CONVERSION" \
"CONFIG_NO_CONVERSION" \
"U_DISABLE_RENAMING" \
)

#will set value to 0
defines_config_set_0=( \
"U_HAVE_NL_LANGINFO_CODESET" \
"UCONFIG_NO_TRANSLITERATION" \
"U_USING_ICU_NAMESPACE" \
)

#will set value to 1
defines_utypes=( \
"U_CHARSET_IS_UTF8" \
)

build.sh

#!/bin/bash

source "../prefix.sh"



function build {
# $1: Toolchain Name
# $2: Toolchain architecture
# $3: Android arch
# $4: host for configure
# $5: additional CPP flags

echo "preparing $1 toolchain"

export PLATFORM_PREFIX=${PWD}/$2-toolchain
export BUILD_DIR=${PWD}/build-$2

#https://developer.android.com/ndk/guides/standalone_toolchain.html
$ANDROID_NDK/build/tools/make_standalone_toolchain.py \
   --api=26 \
   --install-dir=$PLATFORM_PREFIX \
   --stl=libc++ \
   --arch=$3

export PATH=$PLATFORM_PREFIX/bin:$PATH

export CPPFLAGS="-I$PLATFORM_PREFIX/include $CFLAGS -I$ANDROID_NDK/sources/android/cpufeatures $5"
export LDFLAGS="-L$PLATFORM_PREFIX/lib"
export PKG_CONFIG_PATH=$PLATFORM_PREFIX/lib/pkgconfig
export PKG_CONFIG_LIBDIR=$PKG_CONFIG_PATH
export TARGET_HOST="$4"
export CC="$TARGET_HOST-clang"
export CXX="$TARGET_HOST-clang++"
if [ "$ENABLE_CCACHE" ]; then
   export CC="ccache $TARGET_HOST-clang"
   export CXX="ccache $TARGET_HOST-clang++"
fi

mkdir ${BUILD_DIR}
cd ${BUILD_DIR}

sh $ICU_SOURCE/configure --host=$TARGET_HOST -with-cross-build=${PREBUILD} ${CONFIG_PREFIX} --prefix=$PLATFORM_PREFIX

make clean
make -j4
make install

cd ..

mkdir lib/$2

cp ${BUILD_DIR}/lib/* ./lib/$2/

rm -rf ${PLATFORM_PREFIX}
rm -rf ${BUILD_DIR}

}


echo "==============================="
echo "==== Run build for Android ===="
echo "==============================="

mkdir lib

####################################################
# Install standalone toolchain x86

build "x86" "x86" "x86" "i686-linux-android" ""

####################################################
# Install standalone toolchain x86_64

build "x86_64" "x86_64" "x86_64" "x86_64-linux-android" ""


################################################################
# Install standalone toolchain ARMeabi

build "ARMeabi" "armeabi" "arm" "arm-linux-androideabi" ""

################################################################
# Install standalone toolchain ARMeabi-v7a

build "ARMeabi-v7a" "armeabi-v7a" "arm" "arm-linux-androideabi" "-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3"

################################################################
# Install standalone toolchain ARM64-v8a

build "ARM64-v8a" "arm64-v8a" "arm64" "aarch64-linux-android" ""


mkdir include
mkdir include/unicode
cp ${ICU_SOURCE}/common/unicode/*.h ./include/unicode

Upvotes: 0

Views: 879

Answers (1)

Renate
Renate

Reputation: 811

I ran into this problem (for i686, but not for armeabi-v7a) with:

JNINativeMethod natives[]={*whatever*};

I turned it into:

static JNINativeMethod natives[]={*whatever*};

It works fine now. (I'm not sure if it helps you.)

Upvotes: 1

Related Questions