Can't compile NDK android project - android

I am using android studio and openning the hello-jni sample project.
However when I trying to compile the project,it prompts:
Error:Cause: failed to find target with hash string 'android-23' in:
/Users/xx/opensource/android-sdk-macosx
Open Android SDK Manager
I had installed the android 6.0 (api 23).Why still prompts failed to find?
I looked up in the preference in android stuido ,in android SDK tab it seems android 6.0 (api level 23 revision 1) can be found.
Belows is my gradle file:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.0"
defaultConfig.with {
applicationId = "com.example.hellojni"
minSdkVersion.apiLevel = 3
targetSdkVersion.apiLevel = 23
}
}
/*
* native build settings
*/
android.ndk {
moduleName = "hello-jni"
/*
* Other ndk flags configurable here are
* cppFlags += "-fno-rtti"
* cppFlags += "-fno-exceptions"
* ldLibs = ["android", "log"]
* stl = "system"
*/
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.txt')
}
}
android.productFlavors {
// for detailed abiFilter descriptions, refer to "Supported ABIs" #
// https://developer.android.com/ndk/guides/abis.html#sa
create("arm") {
ndk.abiFilters += "armeabi"
}
create("arm7") {
ndk.abiFilters += "armeabi-v7a"
}
create("arm8") {
ndk.abiFilters += "arm64-v8a"
}
create("x86") {
ndk.abiFilters += "x86"
}
create("x86-64") {
ndk.abiFilters += "x86_64"
}
create("mips") {
ndk.abiFilters += "mips"
}
create("mips-64") {
ndk.abiFilters += "mips64"
}
// To include all cpu architectures, leaves abiFilters empty
create("all")
}
}

This worked for me:
I removed the application I was working on in home directory under AndroidStudioProjects
Restarted Android Studio
It prompt the Android Studio Wizard, I went through the Android
Studio Setup Wizard where it downloaded some SDK Build-tools for
revision 23.0.1.
I also clicked on update link when the "Platform and Plugin Updates" message show up while downloading Android SDK Build-tools, to update
some components.
"Welcome to Android Studio" in the Android Setup Wizard will show up,
click on Configure, it will show the Android SDK Manager fetching
some packages as shown in the previous answer, click on new or
updates links
Once the packages are done loading you can go ahead and Install the
available packages. After installing the default selected packages
you may get more that are selected. Install Android SDK License. You
should select each one and then click on accept license. Android
Studio will the go through a gradle build process

I just encountered same problem and I think it is a bug. But I managed to make it work with the following workaround:
First be sure you both install the api and also build-tools (see figure below)
Than in build.gradle, change versions for api and build tools to previous ones: i.e.
android{ compileSdkVersion = 22
buildToolsVersion = "22.0.1"
defaultConfig.with {
applicationId = "com.sample.teapot"
minSdkVersion.apiLevel = 11
targetSdkVersion.apiLevel = 22
}
}
Sync gradle successfully
Change versions back
I also restarted android studio several times but not sure whether it is required or not.

Related

Can't generate x64 version of apks in my project

According to the new Play Store policy * that will take effect in August * I need to ensure that my app provides not only the 32-bit version, but also a 64-bit version, but when I try to generate that version through NDK, I always get the same libs. After trying and trying and trying, I just received an apk without any kind of "lib" folder.
I've tried to set NDK with abiFilters on gradle and got no changes...
defaultConfig {
applicationId "com.myproject.supermidia"
minSdkVersion 17
targetSdkVersion 26
versionCode 20192201
versionName "2.4"
multiDexEnabled true
vectorDrawables.useSupportLibrary = true
}
In order to build for ARM (and the x86 emulator), the splits should look alike this. x86_64 might be a little useless, because the x86_64 emulator is slow and there is no hardware I'd be aware of ...
android {
defaultConfig {
...
externalNativeBuild {
cmake {
arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_CPP_FEATURES=rtti exceptions"
}
}
}
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
}
}
splits {
abi {
enable true
reset()
include "armeabi-v7a", "arm64-v8a", "x86"
universalApk true
}
}
}

How to choose different minSdkVersion for different android ABI?

I have Android app which builds armeabi-v7a and arm64-v8a. Here is the build.gradle:
apply plugin: 'com.android.library'
allprojects {
repositories {
jcenter()
google()
}
}
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
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"
}
}
}
buildTypes {
release {
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
externalNativeBuild {
cmake {
cppFlags "-Wl,--exclude-libs=ALL -Wl,--gc-sections -fvisibility=hidden -fvisibility-inlines-hidden -ffunction-sections"
}
}
}
debug {
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
}
externalNativeBuild {
cmake {
path 'CMakeLists.txt'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
}
I am using the minSdkVersion = 21 to support arm64. I would like to change the minSdkVersion based on the abiFilters i.e., use 16 for v7 and use 21 for arm64.
You don't need to do anything mentioned in the selected answer. Just set minSdkVersion 16 and the 64-bit ABIs will automatically use minSdkVersion 21 because that's the lowest available API for 64-bit.
For how the minSdkVersion property works, see below quotes from official documentation:
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 it has ever been mentioned in may answer to your another question: Android Studio CMake/Ninja Not Used for Building an NDK project.
I am using the minSdkVersion = 21 to support arm64. I would like to change the minSdkVersion based on the abiFilters i.e., use 16 for v7 and use 21 for arm64.
My understanding is that you are trying to support older (api level lower than 21) 32-bit devices without 64-bit native binaries. I would like to say "productFlavor" is the right direction to go. E.g. you can have your gradle configuration like below to achieve what you expect:
android {
...
flavorDimensions "api", "mode"
productFlavors {
minApi16 {
dimension "api"
minSdkVersion 16
versionCode android.defaultConfig.versionCode
versionNameSuffix "-minApi16"
ndk {
abiFilters 'armeabi-v7a'
}
}
minApi21 {
dimension "api"
minSdkVersion 21
versionCode android.defaultConfig.versionCode
versionNameSuffix "-minApi21"
ndk {
abiFilters 'arm64-v8a'
}
}
}
...
}
The minSdkVersion 16 and minSdkVersion 21 will help you choose the best suitable NDK version.
Edit #1
How to choose different minSdkVersion for different android ABI?
minSdkVersion is the property telling the minimum Android version that your app can install on. For one single APK, this is an unconditional characteristic. So:
If you want to have one single APK to support all the devices starting from api 16, then you have to set your minSdkVersion to 16.
If you want to have one single APK to support both 32-bit devices and 64-bit devices, you have to provide a complete set of ALL the shared libraries both 32-bit and 64-bit.
Or else, you have to provide different APKs split by ABIs and minSdkVersion.

Error:The SDK Build Tools revision (24.0.3) is too low for project ':app'. Minimum required is 25.0.0

I'm getting this error when I build the android app:
Error:The SDK Build Tools revision (24.0.3) is too low for project ':app'. Minimum required is 25.0.0
I've looked at other posts, and their solutions didn't work for me. I tried editing build.gradle and changed buildToolsVersion.
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion '24.0.3'
defaultConfig {
applicationId "com.appsofdave.karen"
minSdkVersion 15
targetSdkVersion 23
versionCode 10
versionName "1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
res.srcDirs = ['src/main/res', 'src/main/res/values-v21']
java.srcDirs = ['src/main/java', 'src/main/aidl/com/android/vending/billing']
}
}
repositories {
mavenCentral() // jcenter() works as well because it pulls from Maven Central
}
}
How do I tell gradle to use the Build Tools 23 if it's already installed?
I was successful. First, you have to download the latest version of SDK (25.0.0), save it to a folder. In android studio, select Tools -> android -> SDK manager -> Edit. Select the path to the latest downloaded SDK file. Then run Gradle again!
If it still does not work then you have to download a new Android studio. During the installation process, save the SDK in another folder. In android studio, select Tools -> android -> SDK manager -> Edit. Select the path to the latest downloaded SDK file. Then run Gradle again!

Is there any way to link my native code against prebuilt shared libraries without using the experimental Android Gradle plugin?

I have a project that uses the non-experimental version of the Android Gradle plugin (com.android.tools.build:gradle:2.1.3). I have some native code that I build into a shared library libnative.so.
The problem is that now I want to link libnative.so against a prebuilt library. Let's call this file libfoo.so. If I set the jniLibs.srcDir to the folder containing libfoo.so for the different ABIs I see that it gets bundled into my APK.
However I don't understand how I am supposed to link against it successfully. If I add "foo" to ldLibs I get a linker error saying that it can't find the library. This is probably because the folder containing libfoo.so is not included as a search path to the linker.
How am I supposed to do this? Is it simply not possible without switching to the experimental gradle plugin?
This is my gradle file. I stripped away the part that probably is irrelevant for this problem:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.foo.bar"
minSdkVersion 15
targetSdkVersion 23
versionCode 11
versionName "0.0.11"
def foodir = "${project.buildDir}/../../foo"
ndk {
moduleName "native"
ldLibs "foo"
stl "gnustl_static"
}
sourceSets {
main {
jniLibs.srcDirs = ["${foodir}"]
}
}
}
}

Gradle: change NDK build target independent from the SDK build target

In the past I used eclipse for NDK projects, the Android.mk file was perfectly suited for compiling the NDK with API level 9 while letting the app (SDK) compile on API level 22. But it seems that this is not possible when using the experimental Gradle build system (2.5) with Android Studio 1.3 RC1.
What can I do to compile ONLY the NDK on API level 9?
My typical Android.mk file looks like this:
APP_PLATFORM := android-9
APP_STL := stlport_static
APP_ABI := all
# Enable c++11 extentions in source code
APP_CPPFLAGS += -std=c++11
#Enable optimalization in release mode
APP_OPTIM := release
My new gradle file looks like this:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 22
buildToolsVersion = "23.0.0 rc3"
defaultConfig.with {
applicationId = "com.example"
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 22
versionCode = 1
versionName = "1.0"
}
}
android.ndk {
moduleName = "NativeLibrary"
cppFlags += "-I${file("src/main/jni/some_folder")}".toString()
cppFlags += "-std=c++11"
//What should be added here to compile the NDK on API 9???
CFlags += "-DNDEBUG"
CFlags += "-fvisibility=hidden"
cppFlags += "-fvisibility=hidden"
ldLibs += ["log"]
stl = "stlport_static"
}
android.buildTypes {
release {
isMinifyEnabled = true
proguardFiles += file('D:/path/proguard-rules.pro')
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:support-v4:22.2.0'
}
I investigated the Gradle source and it seems that the NDK build target is hard-coded the same as the compileSdkVersion. Is there an method to avoid or alter this behavior?
NdkCompile.groovy (make file creation)
// target
IAndroidTarget target = getPlugin().loadedSdkParser.target
if (!target.isPlatform()) {
target = target.parent
}
commands.add("APP_PLATFORM=" + target.hashString())
Sdk.groovy (target is fetched form the compileSdkVersion)
public SdkParser loadParser() {
checkNotNull(extension, "Extension has not been set")
// call getParser to ensure it's created.
SdkParser theParser = getParser()
if (!isSdkParserInitialized) {
String target = extension.getCompileSdkVersion()
if (target == null) {
throw new IllegalArgumentException("android.compileSdkVersion is missing!")
}
FullRevision buildToolsRevision = extension.buildToolsRevision
if (buildToolsRevision == null) {
throw new IllegalArgumentException("android.buildToolsVersion is missing!")
}
theParser.initParser(target, buildToolsRevision, logger)
isSdkParserInitialized = true
}
return theParser
}
If you are using the experimental plugin version 0.4. you can set
android.ndk {
platformVersion = "19"
}
Ok, this is a terrible hack, but it is very easy. Find the NDK, it should be in android-sdk/ndk-bundle. Go into the platforms folder. Rename android-21 to something else. Make a copy of android-19, and then copy the three 64-bit folders from android-21 into it, then rename it android-21. Gradle will THINK it's using android-21, and it will for 64-bit targets, but for 32-bit targets it will use android 19.
I'm not 100% sure this is safe, but I tested it on a few devices and I've got an app in Beta Test right now. I think it's cleaner than making gradle tasks for ndk-build. Whenever Google fixes experimental gradle, nothing needs to change other than to reinstall the ndk.
model {
android {
compileSdkVersion = 22
buildToolsVersion '20'
defaultConfig.with {
applicationId = "com.example"
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 22
versionCode = 1
versionName = "1.0"
}
}
gradle version is 3.1.2
defaultConfig {
applicationId "com.xxx.player"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
abiFilters 'armeabi-v7a'
arguments "-DANDROID_PLATFORM=android-21" //config ANDROID_PLATFORM version on here
}
}
}

Categories

Resources