I have updated Android NDK to latest version available and now my project doesn't compile anymore.
At the first attempt to compile the project I received a message about gcc deprecation and invite to replace It with clang.
So I have tried to edit
externalNativeBuild {
cmake {
arguments '-DANDROID_TOOLCHAIN=gcc', '-DANDROID_STL=gnustl_static'
}
}
In
externalNativeBuild {
cmake {
arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'
}
}
But unfortunately now I get the error:
Error while executing process C:\Android\android-sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {-HD:\My Project\myApp\jni -BD:\My Project\myApp\.externalNativeBuild\cmake\release\armeabi-v7a -DANDROID_ABI=armeabi-v7a -DANDROID_PLATFORM=android-21 -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=D:\My Project\myApp\gradleBuild\intermediates\cmake\release\obj\armeabi-v7a -DCMAKE_BUILD_TYPE=Release -DANDROID_NDK=C:\Android\android-sdk\ndk-bundle -DCMAKE_TOOLCHAIN_FILE=C:\Android\android-sdk\ndk-bundle\build\cmake\android.toolchain.cmake -DCMAKE_MAKE_PROGRAM=C:\Android\android-sdk\cmake\3.6.4111459\bin\ninja.exe -GAndroid Gradle - Ninja -DANDROID_TOOLCHAIN=clang -DANDROID_STL=gnustl_static}
The project compilation before the NDK update worked fine.
Don't try to build NDK when the path to your sources contains spaces.
The latest NDK deprecated gnustl, too. Try c++_shared instead.
You don't need to specify ANDROID_TOOLCHAIN in arguments.
Make sure you use a version of gradle Android plugin that is compatible with the latest NDK, see https://developer.android.com/studio/releases/gradle-plugin.
This runtime is tightly coupled to GCC, which is no longer supported in the NDK. As such, it has not received updates for several releases. The version in the NDK supports most of C++11 (see Issue 82), and some portions of this library are incompatible with Clang.
gnustl
This library is deprecated and will be removed in NDK r18. Beginning with NDK r16, you should use libc++ instead.
You should use "-DANDROID_STL=c++_static" instead of -DANDROID_STL=gnustl_static
Related
I have been trying to build a c++ library for android using cmake cross compilation.
The library itself is a trivial test I made purely for testing the androind build process.
I have been using the cmake gui (v 3.25.0) on a windows machine.
I use a visual studio 2019 generator in cmake and specify a toolchain file.
Unfortunately, I seem to get the same error whatever I try. I tried searching for similar problems and trouble shooting, but have so far been unable to make any progress. If anyone with more experience could lend a hand, I would be very grateful!
I have attempted setting many different variables in the toolchain file in an attempt to resolve the problem, but the basic version of what I am working with is:
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_ANDROID_ARCH_ABI armeabi-v7a)
set(CMAKE_ANDROID_NDK C:/Microsoft/AndroidNDK64/android-ndk-r16b/)
The error I run into happens whenever I configure cmake. The outut I get from cmake looks something like this:
Android: Targeting API '27' with architecture 'arm', ABI 'armeabi-v7a', and processor 'armv7-a'
Android: Selected Clang toolchain 'arm-linux-androideabi-clang' with GCC toolchain 'arm-linux-androideabi-4.9'
The C compiler identification is Clang 5.0.300080
The CXX compiler identification is Clang 5.0.300080
Detecting C compiler ABI info
Detecting C compiler ABI info - failed
Check for working C compiler: C:/Microsoft/AndroidNDK64/android-ndk-r16b//toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe
Check for working C compiler: C:/Microsoft/AndroidNDK64/android-ndk-r16b//toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe - broken
CMake Error at C:/Program Files/CMake/share/cmake-3.25/Modules/CMakeTestCCompiler.cmake:70 (message):
The C compiler
"C:/Microsoft/AndroidNDK64/android-ndk-r16b//toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: C:/Users/username/Documents/Code Projects/Android Test/build/CMakeFiles/CMakeScratch/TryCompile-zqgcqm
Run Build Command(s):C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin/MSBuild.exe cmTC_b0f1d.vcxproj /p:Configuration=Debug /p:Platform=x64 /p:VisualStudioVersion=16.0 /v:m && Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
ANDROID_HOME=C:\\Microsoft\AndroidSDK\25
ANT_HOME=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Apps\apache-ant-1.9.3
JAVA_HOME=C:\Program Files\Eclipse Foundation\jdk-8.0.302.8-hotspot
NDK_ROOT=C:\\Microsoft\AndroidNDK64\android-ndk-r16b
testCCompiler.c
clang.exe : warning : argument unused during compilation: '-mthumb' [-Wunused-command-line-argument] [C:\Users\username\Documents\Code Projects\Android Test\build\CMakeFiles\CMakeScratch\TryCompile-zqgcqm\cmTC_b0f1d.vcxproj]
clang.exe : warning : argument unused during compilation: '-mfpu=vfpv3-d16' [-Wunused-command-line-argument] [C:\Users\username\Documents\Code Projects\Android Test\build\CMakeFiles\CMakeScratch\TryCompile-zqgcqm\cmTC_b0f1d.vcxproj]
clang.exe : warning : argument unused during compilation: '-mfloat-abi=softfp' [-Wunused-command-line-argument] [C:\Users\username\Documents\Code Projects\Android Test\build\CMakeFiles\CMakeScratch\TryCompile-zqgcqm\cmTC_b0f1d.vcxproj]
CLANGCOMPILE : error : unknown target CPU 'armv7-a' [C:\Users\username\Documents\Code Projects\Android Test\build\CMakeFiles\CMakeScratch\TryCompile-zqgcqm\cmTC_b0f1d.vcxproj]
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:4 (project)
Configuring incomplete, errors occurred!
I initially used used the NDK version found in the android tools for visual studio found at: "C:/Microsoft/AndroidNDK64/android-ndk-r16b/"
as an NDK version.
I have also tried directly downloading the latest version of the NDK and pointing to that with CMAKE_ANDROID_NDK in the toolchain file, though this did not seem to make any change.
I have tried directly using the toolchain.cmake files found at "NDK/build/cmake/android.toolchain.cmake"
for both the NDK versions described above. This too gave the same error.
Any ideas what could be causing this or how to fix?
Ok, so I was misunderstanding a few things about cross-compiling to android.
First, if I want to be able to use the static library (e.g in android studio), I will need to generate and build a solution for more than one android ABI.
The ABI's to build for are: armeabi-v7a, arm64-v8a, x86_64, x86. I then need to check for each android ABI in the CMakeLists.txt file of Android studio (e.g. elseif(ANDROID_ABI STREQUAL arm64-v8a)) and swap out the location of the library to import to the build folder of that particular ABI.
As far as I am aware, it is unfortunately not possible to generate for all these ABI's as seperate platforms within the same visual studio solution. Given that, cmake must be run 4 seperate times to different build folders, each time targeting a different ABI and generator platform. To save the hassle of doing this manually, creating a batch (.bat) script to automate the process seems the best way to go. This will involve using cmake from the command line instead of the GUI version. The script can also be made to build the generated projects to save opening each one in visual studio and building there.
The batch script I have made to generate and build cross-compilation projects for android is as follows:
#echo OFF
set BUILD_DIR=build
set ANDROID_NDK=C:\Microsoft\AndroidNDK\android-ndk-r23c
set GENERATOR="Visual Studio 17 2022"
set CMAKE_GENERATOR=-G %GENERATOR%
set CMAKE_TOOLCHAIN_FILE=-DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK%\build\cmake\android.toolchain.cmake
set CMAKE_SYSTEM_NAME=-DCMAKE_SYSTEM_NAME=Android
set EXTRA_CMAKE_ARGS=-DBUILD_SHARED_LIBS=true -DANDROID_TOOLCHAIN=clang -DANDROID_STL=c++_static
CALL :build_android armeabi-v7a ARM 16
CALL :build_android arm64-v8a ARM64 21
CALL :build_android x86_64 x64 21
CALL :build_android x86 x86 16
EXIT /B %ERRORLEVEL%
:build_android
set ABI_VERSION=%~1
set GENERATOR_PLATFORM=%~2
set MINIMUM_API_LEVEL=%~3
set CMAKE_ANDROID_ARCH_ABI=-DANDROID_ABI=%ABI_VERSION%
set ABI_BUILD_DIR=%BUILD_DIR%\%ABI_VERSION%
set CMAKE_GENERATOR_PLATFORM=-A %GENERATOR_PLATFORM%
set CMAKE_BUILD_DIR=-B %ABI_BUILD_DIR%
set CMAKE_MIN_API=-DANDROID_PLATFORM=android-%MINIMUM_API_LEVEL%
set CMAKE_ARGS=%CMAKE_BUILD_DIR% %CMAKE_ANDROID_ARCH_ABI% %CMAKE_GENERATOR% %CMAKE_GENERATOR_PLATFORM% %CMAKE_SYSTEM_NAME% %CMAKE_TOOLCHAIN_FILE% %CMAKE_MIN_API%
echo building for android ABI: %ABI_VERSION%
echo cmake arguments = %CMAKE_ARGS%
echo:
cmake %CMAKE_ARGS% %EXTRA_CMAKE_ARGS%
echo:
cmake --build %ABI_BUILD_DIR% --target ALL_BUILD
echo:
echo:
EXIT /B 0
This worked for my simple test library, but I guess depending on the project the arguments to the cmake commands may need to be tweaked.
I am working on an android native project which uses C++ code. I am using CMake to build C++ libraries. I am specifying CMake arguments like this in build.gradle:
cmake {
arguments "--warn-uninitialized",
"-DANDROID_TOOLCHAIN=clang",
"-DANDROID_STL=c++_shared",
"-DANDROID_PLATFORM=android-21",
"-DAPP_ALLOW_MISSING_DEPS=true",
"-DSHARED_LIBRARY=1",
"-DOFFLINE_SYNC_SUPPORT_ENABLED=0",
"-DT5_TARGET_PLATFORM=Android",
"-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a",
"-DANDROID_ABI=armeabi-v7a"
What I want gradle is to build libraries only for armeabi-v7a as specified in cmake arguments but gradle by default is building code for all ABIs.
Though abiFilters can be used in gradle but my gradle build is being invoked by command-line where user has to specify ABI in command line and libs only for that ABI should be built. Like ./gradlew v7 should only build armeabi-v7a libs.
I have the following CMAKE & Ninja installed through Android Studio's SDK Tools:
~/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja --version
1.8.2
I run into "Error Configuring" while trying to build my project. Here is the build output:
Executable : /Users/ssk/Library/Android/sdk/cmake/3.10.2.4988404/bin/cmake
arguments :
-H/Users/ssk/MyProject
-B/Users/ssk/MyProject/.externalNativeBuild/cmake/debug/armeabi-v7a
-DANDROID_ABI=armeabi-v7a
-DANDROID_PLATFORM=android-16
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Users/ssk/MyProject/build/intermediates/cmake/debug/obj/armeabi-v7a
-DCMAKE_BUILD_TYPE=Debug
-DANDROID_NDK=/Users/ssk/Library/Android/sdk/ndk-bundle
-DCMAKE_CXX_FLAGS=-std=c++11
-DCMAKE_SYSTEM_NAME=Android
-DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a
-DCMAKE_SYSTEM_VERSION=16
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
-DCMAKE_ANDROID_NDK=/Users/ssk/Library/Android/sdk/ndk-bundle
-DCMAKE_TOOLCHAIN_FILE=/Users/ssk/Library/Android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake
-G Ninja
-DANDROID_STL=gnustl_statics
-DANDROID_CPP_FEATURES=rtti exception
-DANDROID_TOOLCHAIN=gcc
-DANDROID_NDK=/Users/ssk/android-ndk-r17c/
jvmArgs :
It's missing:
-DCMAKE_MAKE_PROGRAM=/Users/ssk/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja
Error:
CMake was unable to find a build program corresponding to "Ninja". CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool
Only if I switch to CMake version say 3.6.3155560 it works. Otherwise, I have to install ninja from brew or macports.
Here is the snippet from my build.gradle:
externalNativeBuild {
cmake {
// Linker flags and Visibility options keeps the size of the library small
cppFlags "-std=c++11"
arguments "-DANDROID_STL=gnustl_static",
"-DANDROID_CPP_FEATURES=rtti exceptions",
"-DANDROID_TOOLCHAIN=gcc"
}
}
How to fix it?
Install/Update CMake From Android Studio SDK Manager
Check your CMake from sdk root directory if ninja exists.
Below is not good.
cmake {
cppFlags "-std=c++11"
arguments "-DANDROID_ABI=armeabi-v7a",
"-DANDROID_PLATFORM=android-16",
"-DANDROID_STL=gnustl_static",
"-DANDROID_CPP_FEATURES=rtti exceptions",
"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=libs"
}
Because, ANDROID_PLATFORM should be automatically decided by Android external native build system according to minSdkVersion, see below official document from how ANDROID_PLATFORM works:
Instead of changing this flag directly, you should set the minSdkVersion property in the defaultConfig or productFlavors blocks of your module-level build.gradle file. This makes sure your library is used only by apps installed on devices running an adequate version of Android. The CMake toolchain then chooses the best platform version for the ABI you're building using the following logic:
If there exists a platform version for the ABI equal to minSdkVersion, CMake uses that version.
Otherwise,
if there exists platform versions lower than minSdkVersion for the ABI, CMake uses the highest of those platform versions. This is a reasonable choice because a missing platform version typically means that there were no changes to the native platform APIs since the previous available version.
Otherwise, CMake uses the next available platform version higher than minSdkVersion.
And, -DANDROID_ABI=armeabi-v7a is not good as well. You should not define this parameter here. CMake will iterate all your ABIs according to your abiFilters automatically. If you just want to build armeabi-v7a, you can specify this using abiFilter, e.g.
externalNativeBuild {
cmake {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
Also, rtti and exceptions are cppFlags, below should be the proper way to set these two flags.
cppFlags "-std=c++11 -frtti -fexceptions"
Ensure that your have properly configured ANDROID_NDK path, because according to your question, you have TWO version of NDK set, one is -DANDROID_NDK=/Users/ssk/android-ndk-r17c/, the other one is -DANDROID_NDK=/Users/ssk/Library/Android/sdk/ndk-bundle. Config NDK path from local.properties:
ndk.dir=/Users/ssk/Library/Android/sdk/ndk-bundle
sdk.dir=/Users/ssk/Library/Android/sdk
what is the fix for -GAndroid Gradle - Ninja?
Add below arguments to the cmake config:
externalNativeBuild {
cmake {
...
version "3.10.2"
arguments "-GAndroid Gradle - Ninja"
}
}
This is for an Android project using JNI with the NDK. I'm building the project with Android Studio 3.0.1. I recently updated my NDK from version 16 to version 17 in the hopes of making more compiler optimizations available. After the update, I'm getting the following errors:
CMake Error at C:/Users/John/AppData/Local/Android/Sdk/ndk-bundle/build/cmake/android.toolchain.cmake:312 (message):
Invalid Android ABI: armeabi. (armeabi is no longer supported. Use
armeabi-v7a.)
Call Stack (most recent call first):
C:/Users/John/AppData/Local/Android/Sdk/cmake/3.6.4111459/share/cmake-3.6/Modules/CMakeDetermineSystem.cmake:98 (include)
CMakeLists.txt
CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage
CMake Error: CMAKE_CXX_COMPILER not set, after EnableLanguage
-- Configuring incomplete, errors occurred!
I'm getting this error for each of the deprecated ABIs armeabi, mips, and mips64. I understand that I should remove these ABIs from the build, but I can't find instructions on how to do that. I'm not using an Application.mk and I don't see the ABIs being specified anywhere; how can I remove these unused ABIs from my Android Studio project, or better yet, how can I set my project to just use the current non-deprecated ABIs? Thank you.
It should be enough to upgrade your gradle plugin to 3.1.2 or higher, in root (project) build.gradle script. Using the latest plugin is recommended not only to be compliant with latest NDK:
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
}
}
You also must change gradle/wrapper/gradle-wrapper.properties:
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip v.4.4
If you cannot afford such change, you may try to skip the deprecated ABIs for build and packaging:
android {
defaultConfig {
ndk {
abiFilters 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
}
}
packagingOptions {
doNotStrip '*/mips/*.so'
doNotStrip '*/mips64/*.so'
}
}
I'm using NDK r12 with Android Studio 2.2. I need CMake to use GCC 4.9 instead of Clang to build our code base, however even if I provide the following it still uses clang:
android {
compileSdkVersion 17
buildToolsVersion "25.0.0"
defaultConfig {
minSdkVersion 15
targetSdkVersion 17
externalNativeBuild {
cmake {
arguments '-DBUILD_TESTING=OFF -DANDROID_TOOLCHAIN=gcc-4.9'
cppFlags "-std=c++14 -fexceptions -frtti"
}
}
}
}
I've tried -DANDROID_TOOLCHAIN=gcc as well but this doesn't work either. How can I get CMake to use GCC ARM toolchain?
Split your arguments string into one string per argument:
arguments '-DBUILD_TESTING=OFF','-DANDROID_TOOLCHAIN=gcc'
I don't know if it's possible to explicitly specify version 4.9 of GCC ("gcc-4.9" didn't work). However, that's redundant anyway since GCC 4.8 was removed in NDK r11, so GCC 4.9 is now the only version of GCC included in the NDK, and ANDROID_TOOLCHAIN=gcc therefore implicitly means GCC 4.9.
It looks that it's impossible now and GCC toolchaing is dropped.
I get this error when trying to set ANDROID_TOOLCHAIN=gcc:
CMake Error at D:/Android/ndk-bundle/build/cmake/android.toolchain.cmake:169 (message):
GCC is no longer supported. See
https://android.googlesource.com/platform/ndk/+/master/docs/ClangMigration.md