Closed as not planned
Closed as not planned
Description
Hi,
Description
Moving from ndk r21 to r23 we started having issues [1], [2], [3], [4], [5], with some programs failing to be run on device with errors like:
CANNOT LINK EXECUTABLE "tesseract": cannot locate symbol "__extenddftf2" referenced by "/data/data/com.termux/files/usr/lib/libtesseract.so"...
In both cases the issue seem to only happen if the code is compiled using a configure && make system, with a CMakeLists.txt it works fine. After some digging we suspect this happens due to libtool and how it handles the linker flags (see discussion).
One (rather ugly) workaround to solve the issue is to add libclang_rt.builtins-aarch64-android.a as a lib in LDFLAGS. Is there a better solution?
Steps to reproduce
The example below is for aarch64.
# Clone a minimal configure&make project that uses `static_cast<long double>` (which compiles into __extenddftf2)
git clone https://github.com/grimler91/minimal-ndk-r23-issue-example
cd minimal-ndk-r23-issue-example
aclocal
libtoolize --copy
autoconf
automake --add-missing --foreign
# Adjust for path to your ndk
TOOLCHAINROOT=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64
CCPREFIX=$TOOLCHAINROOT/bin/aarch64-linux-android28-
# Optimization level seem to make a difference
CXXFLAGS=-O0 CXX=${CCPREFIX}clang++ CC=${CCPREFIX}clang ./configure --host=aarch64-linux-android --prefix=$(pwd)
make
make install
# Push compiled program, library and libc++_shared to device
adb push bin/main lib/libtest.so $TOOLCHAINROOT/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so /data/local/tmp/
# Try to run the program on device:
adb shell
$ cd /data/local/tmp
$ LD_PRELOAD=./libtest.so:./libc++_shared.so ./main
You should get something like:
WARNING: linker: Warning: "/data/local/tmp/libc++_shared.so" unused DT entry: unknown processor-specific (type 0x70000001 arg 0x0) (ignoring)
CANNOT LINK EXECUTABLE "./main": cannot locate symbol "__extenddftf2" referenced by "/data/local/tmp/libtest.so"...
The __extend* symbols are undefined in libtest.so when compiled like above:
$ readelf -Wa lib/libtest.so | grep __extend
0000000000002938 0000000400000402 R_AARCH64_JUMP_SLOT 0000000000000000 __extenddftf2 + 0
4: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __extenddftf2
35: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __extenddftf2
but for ndk r21, where we linked against libgcc, we get
$ readelf -Wa lib/libtest.so | grep __extend
0000000000001fd0 0000000e00000402 R_AARCH64_JUMP_SLOT 0000000000000704 __extenddftf2 + 0
14: 0000000000000704 248 FUNC GLOBAL DEFAULT 10 __extenddftf2
73: 0000000000000704 248 FUNC GLOBAL DEFAULT 10 __extenddftf2
Environment Details
- NDK Version: 23.1.7779620
- Build system: see above
- Host OS: Linux (ubuntu/archlinux)
- ABI: arm64-v8a
- NDK API level: Tested with 24 and 28
- Device API level: 30