mosra/magnum

Android dumpster fire, again

mosra opened this issue ยท 11 comments

mosra commented

As reported on Gitter by @luigytkd, Magnum is unable to build under Android NDK r19 due to erros like

In file included from /home/lrib/Workspaces/AndroidStudioProjects/magnum/magnum/src/Magnum/Math/Vector.h:32:
/home/lrib/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/cmath:317:9: error: no member named 'isinf' in the global namespace
using ::isinf;

Googling the above doesn't really show anything obvious. NDK r16 is known to work (it's run on Travis CI), NDK r17 (running locally on Arch) works as well. Didn't test with r18 as there's no AUR package. However, when trying to reproduce with r19, I get this during the initial CMake run:

/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ --target=aarch64-none-linux-android --gcc-toolchain=/opt/android-ndk/toolchains//prebuilt/linux-x86_64 --sysroot=/opt/android-ndk/platforms/android-22/arch-arm64  -funwind-tables -no-canonical-prefixes -D__ANDROID_API__=22 -fexceptions -frtti  -g  -fPIE -pie -Wl,--gc-sections CMakeFiles/cmTC_60666.dir/testCXXCompiler.cxx.o  -o cmTC_60666  "/opt/android-ndk/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_static.a" "/opt/android-ndk/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++abi.a" -latomic -nostdlib++ && :
    /..//bin/ld: unrecognised emulation mode: aarch64linux
    Supported emulations: elf_x86_64 elf32_x86_64 elf_i386 elf_iamcu elf_l1om elf_k1om i386pep i386pe
    clang++: error: linker command failed with exit code 1 (use -v to see invocation)

Questions on SO (from end of January) are without answers. Possibly related solution is here, but AFAIK there's no way to force the toolchain path to CMake.

Desperately looking into the CMake bug tracker, I found these two very concerning issues:

Current solution is to go back before r19. r17 (and r16) is known to work well, r18 might work too.

Okay, so, i also spent the whole weekend on trying to make this run, and got it sort of running with a hack, which consist on creating a new toolchain file which invokes the official NDK android toolchain and sets the CMAKE_SYSROOT, here is how i have it:

include(/opt/android-ndk/build/cmake/android.toolchain.cmake)
set(CMAKE_SYSROOT ${ANDROID_SYSROOT})

This assumes your NDK is installed on /opt/android-ndk/. I named this file /opt/android-toolchain.cmake and just invoke it like this:

$ cmake /opt/src/corrade \
        -DCMAKE_TOOLCHAIN_FILE=/opt/android-toolchain.cmake \
        -DCMAKE_SYSTEM_NAME=Android \
        ...other defines...

With this i was able to build corrade, magnum and my android app.

Hope it helps.

mosra commented

Thanks for the info! ๐Ÿ‘

I think this was also the approach suggested by one of the CMake developers in one of the issues linked above -- that they would ditch the builtin support and get the info from the toolchain file bundled in the NDK instead. We'll see how that goes.

For now I'm staying on NDK r17, as that's the path of least resistance :)

Even https://github.com/ruslo/polly doesn't have an r19 android toolchain and it generally has everything! If you get one working then you should contribute it there by adjusting an r18 toolchain to r19 or so!

AFAIK this issue is not really high priority but just in case anyone needs a dirty workaround, applying the above patch in addition to hpcorona's suggestion
termux/termux-packages@8ca3605#diff-3aa9a32da54bb06433e9018c24e7da10
(modifies ndk-included cmath.h and math.h to adjust for CMake messing up system include paths)
actually did the trick in latest stable NDK (r20 at time of writing).

mosra commented

Looking at the upstream GitLab issues linked above, it seems that they managed to firefight all problems and 3.16 could work with the new NDKs again! And they're deciding against removing upstream support in CMake, which is a great thing to hear as well ๐ŸŽ‰

mosra commented

As mentioned in mosra/magnum-bootstrap#21, NDK r20 seems to work even with CMake 3.10 if ANDROID_ABI is explicitly specified.

For now, until 3.16 is out, I'm still treating that as an unsupported scenario, the suggestion is to stay on r17 or older for the time being.

I've just started looking into building for Android. It seems cmake 3.16.2 is now out (https://cmake.org/download/), do we need to update any of the steps for r20 or newer?

mosra commented

Ideally it would "just work" again, but based on past experience I highly doubt that. I'll need to check. Until then, is it possible for you to stay on r17?

Staying on r17 isn't too much of a problem, but just a comment that I've been able to build and make the apk successfully with the toolchain file bundled with the ndk.

Might just be easier to use the ndk toolchain: https://developer.android.com/ndk/guides/cmake

Pasting in the command I'd been using

mkdir build-android-arm64 && cd build-android-arm64
cmake .. \
    -DCMAKE_TOOLCHAIN_FILE="/Users/hkim809/Library/Android/sdk/ndk/20.1.5948944/build/cmake/android.toolchain.cmake" \
    -DANDROID_ABI=arm64-v8a \
    -DANDROID_PLATFORM=22 \
    -DANDROID_STL=c++_static \
    -DANDROID_TOOLCHAIN=clang=clang \
    -DCMAKE_BUILD_TYPE=Release \
    -DCORRADE_RC_EXECUTABLE="../../prebuilt/corrade-rc-osx"
make -j 16
cmake --build . --target install
mosra commented

I managed to get things running again with NDK r19 and CMake 3.17. It only needs some extra help with CMAKE_FIND_ROOT_PATH, but other than that it all works the same way as before. Building instructions updated in 8bc1fa1, the online docs will get updated in a bulk later.

mosra commented

Just a followup, the change done in 8bc1fa1 was still partially using the deprecated / compatibility NDK layout, which led to Gradle not being able to find libraries installed inside the NDK. That's fixed as of mosra/corrade@a0db699 and bc0bb07; with CMake 3.20 it's also no longer needed to supply obvious paths to CMAKE_FIND_ROOT_PATH.