diff --git a/doc/building.dox b/doc/building.dox
index c33886b61..bb54fcf4b 100644
--- a/doc/building.dox
+++ b/doc/building.dox
@@ -690,8 +690,9 @@ installed files. The following variables are supported:
scripts and other files are installed. CMake on Android by default searches
for binaries in <ndk>/platforms/android-<api>/arch-<arch>/usr
based on target API and platform, but looks for headers in a central
- location at <ndk>/sysroot/usr. Defaults to ``.``. If a
- relative path is used, it's relative to `CMAKE_INSTALL_PREFIX`.
+ location at <ndk>/toolchains/llvm/prebuilt/<host>/sysroot/usr.
+ Defaults to ``.``. If a relative path is used, it's relative to
+ `CMAKE_INSTALL_PREFIX`.
Various plugin interfaces search for plugins in locations and order documented
in @ref Corrade::PluginManager::implicitPluginSearchPaths(),
@@ -1027,15 +1028,13 @@ to make it available to depending projects.
You will need [Android NDK](https://developer.android.com/ndk/) installed and
configured and @ref building-corrade-cross-android "Corrade built for Android".
-At least CMake 3.7 is required, as it has Android support built-in. The
-supported toolchain is now Clang with libc++, GCC is not supported anymore.
+The guide assumes NDK r19+ with unified Clang toolchain, which in turn requires
+at least CMake 3.16.
Create a build directory and run `cmake` and the build command in it. Set
`CMAKE_SYSTEM_NAME` to `Android` to enable the crosscompilation,
-`CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION` and `CMAKE_ANDROID_STL_TYPE` to use Clang
-with libc++, `CMAKE_SYSTEM_VERSION` to minimal API version level you wish to
-use and `CMAKE_ANDROID_ARCH_ABI` to target platform ABI. Check the
-[CMake Android cross-compiling documentation](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-android)
+`CMAKE_ANDROID_STL_TYPE` to use libc++, `CMAKE_SYSTEM_VERSION` to minimal API version level you wish to use and `CMAKE_ANDROID_ARCH_ABI` to target platform
+ABI. Check the [CMake Android cross-compiling documentation](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-android)
for further information. You can omit specifying `CORRADE_RC_EXECUTABLE` if
@ref building-cross-corrade-rc "natively-built corrade-rc" is accessible
through `PATH`.
@@ -1044,26 +1043,31 @@ If you set `CMAKE_INSTALL_PREFIX` to `/usr` subdirectory of the particular
Android platform sysroot, the package will get found automatically when
compiling depending projects. Gradle and other Android buildsystems expect
platform-independent includes and other files to be stored in a central
-location, you can set `MAGNUM_INCLUDE_INSTALL_PREFIX` to `/usr` subdirectory of
-the global NDK sysroot. Another option is to explicitly set `CMAKE_PREFIX_PATH`
-to the install location in depending projects.
+location, you can point `MAGNUM_INCLUDE_INSTALL_PREFIX` there to install the
+includes separately. Another option is to explicitly set `CMAKE_PREFIX_PATH`
+to the install location in depending projects. Unfortunately, CMake needs extra
+help with `CMAKE_FIND_ROOT_PATH` to correctly find Android libraries, otherwise
+it falls back to looking in native system locations. Adapt them to your
+system, Android ABI and version and NDK location as needed.
Note that `BUILD_STATIC` is implicitly enabled, because manually loading all
depending shared libraries using JNI would be too inconvenient. The engine is
-built for OpenGL ES 2.0 by default, switch to 3.0 by disabling `TARGET_GLES2`.
+built for OpenGL ES 2.0 by default, switch to 3.0 by disabling `TARGET_GLES2`.
+
+@m_class{m-console-wrap}
@code{.sh}
mkdir build-android-arm64 && cd build-android-arm64
cmake .. \
-DCMAKE_SYSTEM_NAME=Android \
- -DCMAKE_SYSTEM_VERSION=22 \
+ -DCMAKE_SYSTEM_VERSION=24 \
-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \
- -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \
-DCMAKE_ANDROID_STL_TYPE=c++_static \
-DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_INSTALL_PREFIX=/opt/android-ndk/platforms/android-22/arch-arm/usr \
+ -DCMAKE_INSTALL_PREFIX=/opt/android-ndk/platforms/android-24/arch-arm/usr \
+ -DCMAKE_FIND_ROOT_PATH="/opt/android-ndk/platforms/android-24/arch-arm64;/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot" \
-DCORRADE_RC_EXECUTABLE=/path/to/corrade-rc \
- -DMAGNUM_INCLUDE_INSTALL_PREFIX=/opt/android-ndk/sysroot/usr \
+ -DMAGNUM_INCLUDE_INSTALL_PREFIX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr \
-DTARGET_GLES2=OFF \
-DWITH_ANDROIDAPPLICATION=ON
cmake --build .
diff --git a/doc/platforms-android.dox b/doc/platforms-android.dox
index 7e824517a..e55596fab 100644
--- a/doc/platforms-android.dox
+++ b/doc/platforms-android.dox
@@ -38,10 +38,10 @@ namespace Magnum {
The following guide explains how to build Android projects using minimal
command-line tools, without Android Studio involved.
-At the very least you need to have Android SDK and Android NDK installed.
-Running console utilities and tests on the device don't need much more, in case
-you want to develop actual applications, you need also the SDK and a platform +
-SDK platform build tools for version of your choice.
+At the very least you need to have Android SDK and Android NDK installed, the guide assumes NDK r19 and newer. Running console utilities and tests on the
+device don't need much more, in case you want to develop actual applications,
+you need also the SDK and a platform + SDK platform build tools for version of
+your choice.
For APK building it's possible to use either an experimental support in CMake
or the official way with Gradle. Gradle is able to download all the
@@ -55,30 +55,36 @@ for a cleaner setup.
- [android-ndk](https://aur.archlinux.org/packages/android-ndk/)
- [android-sdk-build-tools](https://aur.archlinux.org/packages/android-sdk-build-tools/)
- [android-sdk-platform-tools](https://aur.archlinux.org/packages/android-sdk-platform-tools/)
- - [android-platform-22](https://aur.archlinux.org/packages/android-platform-22/)
+ - [android-platform-24](https://aur.archlinux.org/packages/android-platform-24/)
- [android-sdk-cmake](https://aur.archlinux.org/packages/android-sdk-cmake/)
Gradle requires Android SDK version of CMake, which is currently at version
-3.6. See below for an experimental way to @ref platforms-android-system-cmake "use the system CMake"
+3.10. See below for an experimental way to @ref platforms-android-system-cmake "use the system CMake"
instead. On the other hand, while it's possible to use the CMake from Android
-SDK to build Magnum itself, the following guide is written with CMake 3.7 and
-newer in mind, which has Android support built-in. In older versions you'd need
-to supply a toolchain file instead and the configuration values are different.
+SDK to build Magnum itself, the following guide is written with CMake 3.16 and
+newer in mind, which has Android NDK r19+ support built-in. In older versions
+you'd need to supply a toolchain file instead and the configuration values are
+different.
@section platforms-android-console Building and running console applications
Android allows to run arbitrary console utilities and tests via ADB. Assuming
you have Magnum installed in the NDK path as described in @ref building-cross-android,
-build your project simply as this (adapt version numbers and ABIs as needed):
+build your project as below. The `CMAKE_FIND_ROOT_PATH` is unfortunately needed
+for CMake to correctly find Android libraries, otherwise it falls back to
+looking in native system locations. Adapt paths to your system, Android ABI and
+version and NDK location as needed:
+
+@m_class{m-console-wrap}
@code{.sh}
mkdir build-android-arm64 && cd build-android-arm64
cmake .. \
-DCMAKE_SYSTEM_NAME=Android \
- -DCMAKE_SYSTEM_VERSION=22 \
+ -DCMAKE_SYSTEM_VERSION=24 \
-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \
- -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \
-DCMAKE_ANDROID_STL_TYPE=c++_static \
+ -DCMAKE_FIND_ROOT_PATH="/opt/android-ndk/platforms/android-24/arch-arm64;/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot" \
-DCMAKE_BUILD_TYPE=Release
cmake --build .
@endcode
@@ -87,10 +93,11 @@ After that you can use ADB to upload your executable to the device and run it
there. The global temporary directory is `/data/local/tmp` and while the parent
directories often don't have permissions, it's possible to @cb{.sh} cd @ce into
it and create arbitrary files there. Assuming you built an executable in
-`build-android-arm64/src/my-application`, the workflow would be like this:
+`build-android-arm64/Release/bin/my-application`, the workflow would be like
+this:
@code{.sh}
-adb push build-android-arm64/src/my-application /data/local/tmp
+adb push build-android-arm64/Release/bin/my-application /data/local/tmp
adb shell /data/local/tmp/my-application
@endcode
@@ -404,17 +411,19 @@ After that, you can add the additional ABIs to the `abiFilters` list in your
For example, building Magnum for 32-bit and 64-bit ARM with SDK version 24
could look like this:
+@m_class{m-console-wrap}
+
@code{.sh}
mkdir build-android-arm && cd build-android-arm
cmake .. \
-DCMAKE_SYSTEM_NAME=Android \
-DCMAKE_SYSTEM_VERSION=24 \
-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a \
- -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \
-DCMAKE_ANDROID_STL_TYPE=c++_static \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/platforms/android-24/arch-arm/usr \
- -DMAGNUM_INCLUDE_INSTALL_PREFIX=/sysroot/usr
+ -DCMAKE_FIND_ROOT_PATH="platforms/android-24/arch-arm;/toolchains/llvm/prebuilt/linux-x86_64/sysroot" \
+ -DMAGNUM_INCLUDE_INSTALL_PREFIX=/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr
cmake --build . --target install
cd ..
@@ -424,11 +433,11 @@ cmake .. \
-DCMAKE_SYSTEM_NAME=Android \
-DCMAKE_SYSTEM_VERSION=24 \
-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \
- -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \
-DCMAKE_ANDROID_STL_TYPE=c++_static \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/platforms/android-24/arch-arm64/usr \
- -DMAGNUM_INCLUDE_INSTALL_PREFIX=/sysroot/usr
+ -DCMAKE_FIND_ROOT_PATH="platforms/android-24/arch-arm64;/toolchains/llvm/prebuilt/linux-x86_64/sysroot" \
+ -DMAGNUM_INCLUDE_INSTALL_PREFIX=/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr
cmake --build . --target install
@endcode
@@ -502,7 +511,7 @@ $ adb logcat *:S magnum
According to the [official documentation](https://developer.android.com/studio/projects/add-native-code.html#vanilla_cmake),
it's possible to use system CMake installation without needing to install
-Android SDK version of CMake 3.6. Simply update the
+Android SDK version of CMake 3.10. Simply update the
@cb{.gradle} externalNativeBuild @ce in your `build.gradle` file to specify
CMake version that you have installed in your system, for example:
@@ -513,15 +522,13 @@ android {
cmake {
path 'CMakeLists.txt'
...
- version '3.10.2'
+ version '3.17'
}
}
}
@endcode
-However, be aware that this is an experimental feature and may be broken. At
-the time of writing (March 2018), it didn't work for me with NDK r16b, Android
-buid plugin 3.0.1 and CMake 3.10.
+However, be aware that this is an experimental feature and may be broken.
@section platforms-android-gradlew Using gradlew wrappers instead of a system installation
@@ -743,19 +750,52 @@ gradle build
@section platforms-android-troubleshooting Troubleshooting
-@subsection platforms-android-cmake-too-old CMake is too old
+@subsection platforms-android-cmake-too-old CMake or NDK is too old
While the minimal CMake version that's required for building Magnum for Android
-is 3.7, you might want to grab at least CMake 3.9.2, as it
-[fixes an issue with the Clang toolchain](https://gitlab.kitware.com/cmake/cmake/issues/17253).
+is 3.7, NDK r19 and newer need at least CMake 3.16 to work. For older NDKs you
+might want to grab at least CMake 3.9.2, as it [fixes an issue with the Clang toolchain](https://gitlab.kitware.com/cmake/cmake/issues/17253).
+
+With NDK r18 and older you'll need to additionally supply
+`-DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang`, on the other hand the
+`-DCMAKE_FIND_ROOT_PATH` isn't needed --- CMake is able to figure out the paths
+on its own in that case.
-@subsection platforms-android-ndk-too-new NDK is too new
+@subsection platforms-android-compiler-fails-at-life Compiler suddenly fails at life
+
+If you're suddenly greeted with an overwhelming amount of strange errors coming
+from standard library C++ headers including things like
+
+@m_class{m-console-wrap}
+
+@code{.shell-session}
+/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/include/c++/v1/cmath:319:9: error: no member named 'isnormal' in the global namespace
+using ::isnormal;
+ ~~^
+/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/include/c++/v1/cmath:320:9: error: no member named 'isgreater' in the global namespace
+using ::isgreater;
+ ~~^
+/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/include/c++/v1/cmath:321:9: error: no member named 'isgreaterequal' in the global namespace
+using ::isgreaterequal;
+ ~~^
+/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/include/c++/v1/cmath:322:9: error: no member named 'isless' in the global namespace
+using ::isless;
+ ~~^
+/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/include/c++/v1/cmath:323:9: error: no member named 'islessequal' in the global namespace
+using ::islessequal;
+ ~~^
+/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/bin/../sysroot/usr/include/c++/v1/cmath:324:9: error: no member named 'islessgreater' in the global namespace
+using ::islessgreater;
+ ~~^
+@endcode
+
+@m_class{m-noindent}
-Last NDK version that's known to be reliably working with CMake is r17, newer
-versions suffer from various issues due to changes introduced in NDK internals.
-No work has been done yet on Magnum side to counter / work around those issues,
-optimistically waiting on CMake devs to figure it out instead. See
-[mosra/magnum#310](https://github.com/mosra/magnum/issues/310) for details.
+it might be due to `<ndk>/sysroot/usr/include` being present in your
+include path. For some reason the NDK has two copies of system includes, one in
+`<ndk>/toolchains/llvm/prebuilt/<host>/sysroot/usr` and one here,
+and the one in `<ndk>/sysroot` causes the above errors. Find the
+offending include dir and point it to the other location to fix the error.
@subsection platforms-android-troubleshooting-windows-nsight CMake complaining about some NVIDIA Nsight Tegra Visual Studio Edition on Windows
diff --git a/package/archlinux/PKGBUILD-android-arm64 b/package/archlinux/PKGBUILD-android-arm64
index 8572eee98..a10451357 100644
--- a/package/archlinux/PKGBUILD-android-arm64
+++ b/package/archlinux/PKGBUILD-android-arm64
@@ -19,19 +19,20 @@ build() {
cmake .. \
-DCMAKE_SYSTEM_NAME=Android \
- -DCMAKE_SYSTEM_VERSION=22 \
+ -DCMAKE_SYSTEM_VERSION=24 \
-DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \
- -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \
-DCMAKE_ANDROID_STL_TYPE=c++_static \
+ -DCMAKE_FIND_ROOT_PATH="/opt/android-ndk/platforms/android-24/arch-arm64;/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot" \
-G Ninja
+
fi
cd "$_rootdir/build-android-arm64"
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
- -DCMAKE_INSTALL_PREFIX=/opt/android-ndk/platforms/android-22/arch-arm64/usr \
- -DMAGNUM_INCLUDE_INSTALL_PREFIX=/opt/android-ndk/sysroot/usr \
+ -DCMAKE_INSTALL_PREFIX=/opt/android-ndk/platforms/android-24/arch-arm64/usr \
+ -DMAGNUM_INCLUDE_INSTALL_PREFIX=/opt/android-ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr \
-DWITH_ANYAUDIOIMPORTER=OFF \
-DWITH_ANYIMAGECONVERTER=ON \
-DWITH_ANYIMAGEIMPORTER=ON \
@@ -55,3 +56,5 @@ package() {
cd "$_rootdir/build-android-arm64"
DESTDIR="$pkgdir/" ninja install/strip
}
+
+# kate: hl bash