Android Studio 2.3 CMake doesn't show errors and won't compile C++ code - android-studio

So I'm trying to write my first native library to reuse my C++ code in Android and iOS but just cannot get it to run under Android Studio 2.3
I followed the instructions to the letter (I hope) which mostly consist of:
Write a CMakeLists.txt file containing (in my case):
cmake_minimum_required(VERSION 3.4.1)
add_library(
test-lib
STATIC
src/main/cpp/test.cpp
src/main/cpp/cpp_wrapper.cpp)
include_directories(src/main/cpp/include/)
find_library(
log-lib
log )
target_link_libraries(test-lib ${log-lib} )
add_library( app-glue
STATIC
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )
target_link_libraries( test-lib app-glue ${log-lib} )
Then link the CMake file to gradle in your modules build.gradle file
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion '25.0.2'
defaultConfig {
applicationId 'com.mysample.id'
minSdkVersion 19
targetSdkVersion 25
versionCode 9
versionName "1.3.0"
}
buildTypes {
release { ... }
}
productFlavors {
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
repositories {
maven { ... }
}
dependencies { ... }
That should be sufficient. Sadly its not.
I just can't figure out what I'm missing here.
Once (and really only once) I actually got an error message from CMake because of an intentionally placed typo in the cpp file, but that was the only thing I ever saw from it. No library *.so file is created, and of course none is packaged with the apk, so the app crashes as soon as it tries to load it.
Update: I was looking in the wrong place, there actually are some files from CMake in app/.externalNativeBuild/cmake which reflect build configurations and cpu architectures and they even include an test-lib.dir directory, but this is empty. I looked through the files to see if there is some clue but couldn't find anything interesting.
Any suggestions welcome!

In the end, I created a new project, carried out all instructions (again), copied my already existing work over to the new one, voilà.
We'll probably never know what the cause was...

Related

Android studio 3.0: Unable to resolve dependency for :app#dexOptions/compileClasspath': Could not resolve project :animators

I migrate to Android studio 3.0. So, the project become unable to compile a module named ":animator" and it displays me this error:
Error:Unable to resolve dependency for
':app#dexOptions/compileClasspath': Could not resolve project
:animators. <a
href="openFile:/home/mobilepowered/MobilePowered/MyInnovalee/trunk17-10-2017/app/build.gradle">Open
File</a><br><a href="Unable to resolve dependency for
':app#dexOptions/compileClasspath': Could not resolve project
:animators.">Show Details</a>
and show details gives this log :
Unable to resolve dependency for ':app#dexOptions/compileClasspath':
Could not resolve project :animators.
Could not resolve project :animators. Required by:
project :app
Unable to find a matching configuration of project :animators:
- Configuration 'debugApiElements':
- Required com.android.build.api.attributes.BuildTypeAttr 'dexOptions' and found incompatible value 'debug'.
- Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and
found compatible value 'Aar'.
- Found com.android.build.gradle.internal.dependency.VariantAttr 'debug' but
wasn't required.
- Required org.gradle.api.attributes.Usage 'java-api' and found compatible value 'java-api'.
- Configuration 'debugRuntimeElements':
- Required com.android.build.api.attributes.BuildTypeAttr 'dexOptions' and found incompatible value 'debug'.
- Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and
found compatible value 'Aar'.
- Found com.android.build.gradle.internal.dependency.VariantAttr 'debug' but
wasn't required.
- Required org.gradle.api.attributes.Usage 'java-api' and found incompatible value 'java-runtime'.
- Configuration 'releaseApiElements':
- Required com.android.build.api.attributes.BuildTypeAttr 'dexOptions' and found incompatible value 'release'.
- Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and
found compatible value 'Aar'.
- Found com.android.build.gradle.internal.dependency.VariantAttr 'release' but
wasn't required.
- Required org.gradle.api.attributes.Usage 'java-api' and found compatible value 'java-api'.
- Configuration 'releaseRuntimeElements':
- Required com.android.build.api.attributes.BuildTypeAttr 'dexOptions' and found incompatible value 'release'.
- Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and
found compatible value 'Aar'.
- Found com.android.build.gradle.internal.dependency.VariantAttr 'release' but
wasn't required.
- Required org.gradle.api.attributes.Usage 'java-api' and found incompatible value 'java-runtime'.
With Android Studio 2.3(AS) the project works fine and i can able to run the App. After updating the AS to Android Studio 3.0. i too got the error as below for libraries and build types.
Unable to resolve dependency for ':app#dexOptions/compileClasspath': Could not resolve project : library_Name.
Unable to resolve dependency for ':app#release/compileClasspath': Could not resolve project : library_Name.
To Solve the issue, simply.
What ever the
buildTypes{
debug{ ... }
release{ ... }
}
you have in your (app) build.gradle file, You have to include all the buildTypes{ } with same names as like
buildTypes{
debug{ ... }
release{ ... }
}
in to build.gradle files of All libraries/modules included in project.
clean and rebuild the project, the issue will be fixed.
Still issue not fixed, update the gradle-wrapper.properties to
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
As stated in the official migration guide, this error is encountered when:
Your app includes a build type that a library dependency does not
android {
buildTypes {
release {
...
}
dexOptions {
...
// release & debug is in project animators
matchingFallbacks = ['release', 'debug']
}
debug {
...
}
}
}
Correct place to find the info is now this documentation
Make sure you're in your project
Open the Preferences, by clicking File > Settings (on Mac,
Android Studio > Preferences).
In the left pane, click Build, Execution, Deployment >> Gradle.
Uncheck/disable the Offline work checkbox.
Click Apply or OK.
I spent a lot of time on this issue and none of above solutions work for me. The names and number of build types were also exactly equal in both app and library project.
The only mistake I was making was - In library project's build.gradle, I was using line
apply plugin: 'com.android.application'
While this line should be -
apply plugin: 'com.android.library'
After making this change, this error got resolved.
Modify all
compile project(':library:yourproject')
to
implementation project(path: ':library:yourproject', configuration:'default')
in your app build.gradle. Note the line with configuration.
I tried everything from unchecking offline work to matchingFallbacks. But nothing worked.
Then, in dependencies of app.gradle,
instead of
implementation project(':lib-name')
I used,
implementation project(path:':lib-name', configuration: 'default')
Eg: implementation project(path:':myService', configuration:
'default')
And it worked like a charm. :)
I was adding a dependency module with service and am not making a library as its a part of AOSP project.
Just in case, it helps someone.
Solution:
Dowload the ultimate version of Gradle
http://services.gradle.org/distributions/
gradle-4.x-rc-1-all.zip.sha256 09-Jan-2018 01:15 +0000 64.00B
Unzip the distribution
Go to Android Studio -> File -> Settings -> Gradle -> Use local gradle distribution
Search the file and OK
In the gradle:app write this, implementation(path: ':animators', configuration: 'default')
dependencies {
.
.
.
implementation project(path: ':animators', configuration: 'default')
}
Here is how I solved my problem:
instead of
compile project(':library_name')
compile project(':library_name')
in app gradle I have used
implementation project(':library_name')
implementation project(':library_name')
And in my build types for example
demoTest {
.........
}
I added this line
demoTest {
matchingFallbacks = ['debug', 'release']
}
I had the same issue, and solved it by adding 'mavenCentral()' to build.gradle(Project)
allprojects {
repositories {
...
mavenCentral()
}
}
My problem is below
Unable to resolve dependency for ':app#debug/compileClasspath': Could not download rxjava.jar (io.reactivex.rxjava2:rxjava:2.2.2)
Solved by checking Enable embedded Maven Repository
Even, I have faced the same issue.
I have fixed the issue by referring the above
Solution 2 with the new g‌​radle-4.1 :
I have done the following gradle changes.
It seems downloading resources through maven Amazon helped me to fix the issue, there are issues with appcompat library. Check and ensure that appcompat compatible support libraries downloaded in your system. What I feel, it just simply the resources not downloaded through maven, causing the compile error issue. Ensure the resources are found in your local drive to fix the issue.
Just Played around with
Maven Amazon url
repositories {
maven {
url "https://s3.amazonaws.com/repo.commonsware.com"
}
jcenter()
}
Compatible support libraries downloaded in the drive and referring compatible libraries in gradle.
dependencies {
implementation fileTree(dir: 'libs', include: \['*.jar'\])
implementation 'com.android.support:appcompat-v7:26.0.0-alpha1'
implementation 'com.android.support:support-v4:26.0.0-alpha1'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}
Complete file
apply plugin: 'com.android.application'
repositories {
maven {
url "https://s3.amazonaws.com/repo.commonsware.com"
}
jcenter()
}
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.cognizant.interviewquestions.cognizantiqpractice2"
minSdkVersion 18
targetSdkVersion 26
versionCode 1
versionName "1.0"
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath false
}
}
dexOptions {
javaMaxHeapSize "4g"
preDexLibraries = false
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: \['*.jar'\])
implementation 'com.android.support:appcompat-v7:26.0.0-alpha1'
implementation 'com.android.support:support-v4:26.0.0-alpha1'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}
---------------------------------------------------------------------------
Change this code in gradle:
compile project(':yourLibrary')
to
implementation project(path: ': yourLibrary', configuration:'default')
I found two type of solutions :
Solution with the old g‌​radle-3.3 :
As first and temporary solution to make the project run with android studio 3.0 , I maintain the old config of my previous of Android Studio 2.3
distributionUrl=https://services.gradle.org/distributions/g‌​radle-3.3-all.zip , compileSdkVersion 25** and **buildToolsVersion "25.0.3" and classpath 'com.android.tools.build:gradle:2.3.3
Solution with the new g‌​radle-4.1 :
To work with the new features of gradle 4.1 and the classpath com.android.tools.build:gradle:3.0.0' , I followed this link https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html . So, Those are my implementations :
In the file gradle-wrapper.properties :
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
In the file build.gradle of the project :
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
//classpath 'me.tatarka:gradle-retrolambda:3.3.1' remove this line
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
In the file build.gradle of the app :
apply plugin: 'com.android.application'
//apply plugin: 'me.tatarka.retrolambda' remove this line
repositories {
maven {
url "https://s3.amazonaws.com/repo.commonsware.com"
}
jcenter()
mavenCentral()
maven { url "https://jitpack.io" }
}
android {
compileSdkVersion 26
buildToolsVersion "26.0.2"
defaultConfig {
applicationId "com.imennmn.myprojectid"
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
/**
* Enabling multidex support.
*/
multiDexEnabled true
missingDimensionStrategy 'minApi' , 'minApi24'
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath true
}
}
dexOptions {
javaMaxHeapSize "4g"
preDexLibraries = false
}
}
buildTypes {
release {
shrinkResources false
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
configurations.all {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
}
/**
* Solve the problem when using multiple free source libs
* NOTICE or LICENSE files cause duplicates
*/
packagingOptions {
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
exclude 'META-INF/DEPENDENCIES'
//exclude duplicate butterknife and parceler libs
exclude 'META-INF/services/javax.annotation.processing.Processor'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/rxjava.properties'
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation files('libs/motwin-android-sdk-3.2.0-RELEASE-TLS.jar')
implementation files('libs/notifmanager-android-lib-3.1.0-RELEASE.jar')
implementation files('libs/commons-lang-2.4.jar')
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'com.android.support:appcompat-v7:26.0.2'
implementation 'com.android.support:support-v4:26.0.2'
implementation 'com.android.support:design:26.0.2'
implementation 'com.android.support:multidex:1.0.2'
api 'com.jakewharton:butterknife:7.0.1'
implementation 'de.hdodenhof:circleimageview:2.1.0'
implementation 'com.android.support:percent:26.0.2'
implementation 'com.google.android.gms:play-services-maps:11.4.2'
implementation 'com.github.bumptech.glide:glide:3.7.0'
implementation 'com.google.code.gson:gson:2.8.1'
testImplementation 'junit:junit:4.12'
implementation 'com.facebook.rebound:rebound:0.3.8'
implementation 'com.google.android.gms:play-services-gcm:11.4.2'
implementation 'io.reactivex.rxjava2:rxjava:2.1.1'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation project(':animators')
// Retrofit2 & XmlConverter
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
implementation('com.squareup.retrofit2:converter-simplexml:2.3.0') {
exclude group: 'xpp3', module: 'xpp3'
exclude group: 'stax', module: 'stax-api'
exclude group: 'stax', module: 'stax'
}
implementation 'com.squareup.okhttp3:okhttp:3.4.1'
implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1'
//Library to reports crash
implementation('ch.acra:acra:4.5.0') {
exclude group: 'org.json'
}
implementation 'com.github.kenglxn.QRGen:android:2.3.0'
}
In the build.gradle of the library animator I upgrade targetSdkVersion to 26 :
apply plugin: 'com.android.library'
android {
compileSdkVersion 26
buildToolsVersion '26.0.2'
defaultConfig {
minSdkVersion 21
targetSdkVersion 26
versionCode 1
versionName "1.0"
}
}
dependencies {
implementation "com.android.support:support-compat:26.0.2"
implementation "com.android.support:support-core-ui:26.0.2"
implementation "com.android.support:recyclerview-v7:26.0.2"
}
you just need to reset dependencies in app.gradle file
like old one as
androidTestImplementation 'com.android.support.test:runner:0.5'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2'
to new one as
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
Make sure you have disabled "Offline work" in Gradle settings (Setting->Build, Execution, Deployment->Build Tools->Gradle).
I made this mistake. I followed a guide on speeding up gradle builds and had turned on the Offline work option. If that is enabled, Gradle won't be able to download any new dependencies and hence will result in the "Unable to resolve dependency" error.
I met the same problems and has solved.
Due to my situation, I guess your build.gradle file for app project contains snippets below:
android {
...
buildTypes {
debug {...}
release {...}
dexOptions {...}
}
}
but actually, dexOptions is not a build type, you should move dexOptions section out buildTypes, like this:
android {
...
dexOptions {
...
}
buildTypes {
debug {...}
release {...}
}
}
Hope that can help someone.
Adding productFlavors{} to the app build.gradle solved the issue for me. See below:
buildTypes {
release {
...
}
}
productFlavors {
}
This may also happen when you add a reference to the feature module that uses the incorrect plugin type. Simply change com.android.application to com.android.feature or com.android.library
https://i.stack.imgur.com/NDjnG.png
I think it's from gradle-wrapper.properties file :
make distribution url distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
and do not upgarde to : distributionUrl=https\://services.gradle.org/distributions/gradle-4 ....
It seems like it's a bug on Gradle. This solves the problem for me, but it's not a solution. We have to wait for a new version fixing this problems.
On build.gradle in the project set classpath 'com.android.tools.build:gradle:2.3.3' instead classpath 'com.android.tools.build:gradle:3.0.0'.
On gradle-wrapper.properties set https://services.gradle.org/distributions/gradle-3.3-all.zip instead https://services.gradle.org/distributions/gradle-4.1.2-all.zip
In my case, the problem I had was due to a dependency I was trying to import (BottomNavigationViewEx).
This dependency requires to be downloaded from jitpack.io and maven.google.com, and I was putting this config in buildscript section:
buildscript {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" } // this is incorrect
maven { url "https://maven.google.com" } // this is incorrect
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
}
}
which it was incorrect, I need to remove these two maven lines and include them in the right section, 'allprojects':
allprojects {
repositories {
google()
jcenter()
maven { url "https://jitpack.io" }
maven { url "https://maven.google.com" }
}
}
Hope it helps somebody as same for me.
I tried all the solutions given above and none of them worked for me, I ensured that I have exact build types and product flavours in my library module and app module.
This thread seems to have wondered a bit, however as relating to the original question, not only do you have to have your buildTypes in both build.gradle files, you need to have your productFlavors (if you are using them of course) in both build.gradle files as well.
I tried running Android studio 3.0.1 with internet connection. Android studio started downloading something from a link automatically which was showing in Gradle build notification. I can't say this is a sure answer but try this out.. maybe you can get your issue resolved.
If using Android Studio on Linux:
go to: Home/Android Studio Projects folder/App name folder
open terminal on that page and type:
./gradlew -Dhttp.proxyHost
check if JAVA_HOME is set on valid directory, if not set valid location finally rebuild your project.
NOTE: if that doesn't work remove gradle cache folder or all of that
and download again with Android Studio.
Add the library from File->Right click->New->Module->Import Eclipse ADT project->brows your library->finish
Now add in the app gradle setting following code:
implementation project(':library')
Finally add in the setting gradle following code:
include ':app', ':library'
After updating android studio to 3.3. I faced this problem when I tried to load Firebase JobDispatcher.
Adding this link on gradle.properties solved my problem
distributionUrl=https://services.gradle.org/distributions/gradle-4.1-all.zip
I know none of the above solutions is gonna work as I have remained stuck into this sort of issue a long time, finally resolved this issue after watching the issue very carefully, which is pointing that
Unable to resolve dependency for ':app#dexOptions/compileClasspath':
Could not resolve project : library_Name.
You need to make a sure and double check if the class is residing there. This one thing will prove much helpful to many I guess because focusing on this point took me much closer to the solution. Now if nothing exists in that folder path you need to get the whole stuff like src folder build folder etc everything, copy that and paste it over there sync/rebuild project, if needed try invalidate and restart android studio. Hope so this will get you out of trouble as happend in my case.
Thanks
changing implementation 'com.android.support:appcompat-v7:27+' to implementation 'com.android.support:appcompat-v7:+' worked for me
I am using Intellij 2019 CE, with Kotlin
In my case it was so:
Unable to resolve dependency for ':app#debug/compileClasspath': Failed to transform artifact....
I tried ten solutions, no one worked, thus my solution was to remove C:\Users\djdance.gradle\caches and restart AS

How to Import Github non Android Studio Project as library into Android Studio?

I am trying to import standout library which is a github project as library in my project.What i tried is below:
created a folder in my root project directory named 'libs'
copied the complete folder 'library' of the Standout project on git into 'libs'
renamed the folder 'library' that i just copied to e.g. "standout" (just to avoid confusion)
now added this library in my settings.gradle with the following command:
include ':libs:standout'
going to my build.gradle file of my AppProject and added the following line to my 'dependencies':
compile project(':libs:standout')
but i got error and then added like this
compile fileTree(dir: 'libs', include: ['standout'])
gradle sync was successful but there is red mark on the src files of the library project..I couldn't access the library src files from MainActivity of my Project.As the github project wasn't the android studio project do i need to do anything extra for that?
I have tried below way suggested by Wesley:
Download or clone the git repository, copy the library folder into
your project root folder.
Then in your project settings.gradle file, add a ':library' at the
end of the include line, like this: include ':app', ':library', then
gradle sync your whole project.
At the end, in your app module or you own application module, edit
the build.gradle file, add a line in your dependencies:
compile project(':library')
BTW, you can change the folder name ("library" in this case) to any
name you want (like "standout-library" if you want) when copy it into
you project's root folder, then, when you edit the gradle files, just
use the changed name.
But got the below error:
Error:Configuration with name 'default' not found.
My build.gradle:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.mapandmap.standout"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':standout')
compile 'com.android.support:appcompat-v7:22.1.1'
}
My settings.gradle:
include ':app',':standout'
screenshot of my Project Tree:
You need to resolve R in each file of "standout" library which is showing as red now.
You can simply add by doing this. Go to Android Studio File->Project Structure-> + , You will get four options to add a new module. From there choose "Import Existing Project"->Next-> browse to the directory you have downloaded library and choose "library" directory and then "Finish".Android Studio will take some time to sync library to your project. Finally add dependency in settings. I just tested by adding this library in a project and its working perfectly.
You could move the library to your main "app" project but its better to add as dependency.
I followed the answer of sbr1308 but I have to do some more things.What you have to do:
Go to Android Studio File->Project Structure-> + , You will get four options to add a new module. From there choose "Import Existing Project"->Next-> browse to the directory you have downloaded library and choose "library" directory and then "Finish"
If there is any error in the classes of the library then Go to File->Invalidate Caches/Restart->Invalidate and Restart.It will take time to indexing.
You have to add the dependency in the app's build.gradle
compile project(':standOut') and then sync.

java.lang.UnsatisfiedLinkError: Couldn't load from loader dalvik.system.PathClassLoader findLibrary returned null

I understand this is asked many times, but I have done thorough research before posting my query.
I have updated Android Studio to latest version as of March 2nd 2015, version 1.1.0. I think still grade does not package .so files on its own.
I have written NewNDK.c in /jni folder. Ran the ndk-build script and .so files were created in /libs. As per suggestion in one of the posts, I modified libs to lib.
Even then, I am getting java.lang.UnsatisfiedLinkError: Couldn't load from loader dalvik.system.PathClassLoader findLibrary returned null error.
The posts does not say about which files to modify. I am new to Android, request your help.
I have narrowed down the problem to: 1. Gradle is not packaging 2. Gradle scripts should be modified.
The build.gradle (Module: app) is as below:
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.raghu.newndk"
minSdkVersion 17
targetSdkVersion 17
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
The build.gradle (project) is as below:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
Please let me know what is missing.
Thank You!
As per suggestion in one of the posts, I modified libs to lib.
It doesn't really make sense to do that. lib is the folder where your .so files will go inside the APK, but this step will be handled directly by the packaging tools if your project is correctly organized.
Inside an Android Studio project, you should put the .so files inside jniLibs/<ABI> where <ABI> is the target architecture of each .so file (armeabi, x86... the same way that they are generated from the NDK inside libs).
So you can either rename your libs folder to jniLibs, or configure your build so your .so files from libs will be directly integrated:
android {
...
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
}
}
Open the project properties > go to Andriod options > select Advance tab > just uncheck "armeabi","armeabi-v7a","arm64-v8a" and save the project.
The Error will be removed.

How to port C library into into Android studio JNI folder

I have a program, which I have compiled using the arm toolchain in NDK. Now I want to use it as a library; put it in the JNI folder and call the functions from my main activity. I want to know how to go about this efficiently and intelligently. I copied all the files, and folders over to the JNI folder. What do I do about the make files in my native C code? Can I modify them to fit the JNI setup? Can anyone help with what items I need to address please? Note, my question is not about porting the native code, rather how to do it effectively. And I am trying to figure out if there are any automation tools in IDE that would help me do this please.
Right now, I get the following error, which I believe tells me that the old make file I copied over is not producing a file that is needed by the project? Am I right?
Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.internal.LoggedErrorException: Failed to run command:
/home/sansari/ndk/android-ndk-r10d/ndk-build NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/home/sansari/AndroidStudioProjects/NDKSample/app/build/intermediates/ndk/debug/Android.mk APP_PLATFORM=android-21 NDK_OUT=/home/sansari/AndroidStudioProjects/NDKSample/app/build/intermediates/ndk/debug/obj NDK_LIBS_OUT=/home/sansari/AndroidStudioProjects/NDKSample/app/build/intermediates/ndk/debug/lib APP_ABI=all
Error Code:
2
Output:
make: *** No rule to make target `/home/sansari/AndroidStudioProjects/NDKSample/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/objs/myLib//home/sansari/AndroidStudioProjects/NDKSample/app/src/main/jni/tools/arm-eabi-4.7/lib/gcc/arm-eabi/4.7/crtn.o', needed by `/home/sansari/AndroidStudioProjects/NDKSample/app/build/intermediates/ndk/debug/obj/local/arm64-v8a/libmyLib.so'. Stop.
Here is my build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.sansari.ndksample"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
ndk {
moduleName ="myLib"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
The story behind this project is that I created it using a tutorial. In it, the author used mylib. So the error I am getting says that the make file I just moved into the JNI folder does not have a line for building mylib.so. Is that right? I looked at the make file at the root of my C code, and that does not look anything like target/dependency structure that I read about in the first few chapters of GNU make. Can you help me find the make file I need to update in order to build mylib.so?
I found some information about my question. By default build.gradle ignores the existing make files in a native project. And you have to put in your own Android.mk and Application.mk files in the Android Studio.
I found out I have to add Android.mk and application.mk to a native project in Android Studio if I am looking to port a large project into Android Studio.

How to configure NDK with Android Gradle plugin 0.7

The new Android gradle plugin (0.7) seems to include new support for the NDK, but in the documentation there is little to no mention of it (the only reference I found is a test called ndkSanAngeles).
It looks like gradle is looking for the NDK, which I have included in my PATH. However, building the project fails with
What went wrong:
Execution failed for task ':OGLTests:compileDefaultFlavorDebugNdk'.
NDK not configured
How can I configure the NDK in gradle?
My current build.gradle looks like this:
task nativeLibsToJar(type: Zip, description: 'create a jar with native libs') {
destinationDir file("$buildDir/native-libs")
baseName 'native-libs'
extension 'jar'
from fileTree(dir: 'src/main/libs', include: '**/*.so')
from fileTree(dir: 'src/main/libs', include: '**/gdb*')
into 'lib/'
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn nativeLibsToJar
}
dependencies {
compile fileTree(dir: "$buildDir/native-libs", include: '*.jar')
}
android {
compileSdkVersion 19
buildToolsVersion '19.0.0'
defaultConfig {
minSdkVersion 14
targetSdkVersion 19
versionCode 1
versionName "0.1"
}
buildTypes {
release {
runProguard false
}
debug {
// jniDebugBuild true
runProguard false
debuggable true
}
}
productFlavors {
defaultFlavor {
proguardFile 'proguard-rules.txt'
}
}
}
Thanks.
Looking through the gradle plugin code, I found the following that helped me use both NDK and prebuilt native libraries:
To simply Link in Prebuilt Native Libraries, just add an ndk section to your task. For instance, I added it below in productFlavors. The abiFilter is the folder name the libs are stored in. abiFilters means both libs from the comma separated list will be added to your final APK (so you could theoretically have "armeabi", "armeabi-v7a", "x86", and "mips" all in one APK, and the O/S would choose the supported architecture lib on install):
productFlavors {
arm {
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
}
x86 {
ndk {
abiFilter "x86"
}
}
}
In this example, the arm build will create an APK with the V5 and V7A arm libs in it, and the x86 build will create an APK with just x86 libs in it. This will search for the native libraries in your project jniLibs directory. The jniLibs directory should be structures as the old jni directory, i.e.:
[project]/[app]/src/main/jniLibs/armeabi/libmyNative.so
[project]/[app]/src/main/jniLibs/armeabi-v7a/libmyNative.so
[project]/[app]/src/main/jniLibs/x86/libmyNative.so
Then you can load it in Java as follows:
static
{
loadLibrary("myNative");
}
Now, let's say one native library depends on another one. You MUST (if setting your min API to API 17 or lower) load the dependent libraries first:
static
{
loadLibrary("myDependency");
loadLibrary("myNative");
}
You can also place the ndk {} section in your defaultConfig or a buildType (such as debug or release or whatever else you may use). For example:
buildTypes {
debug {
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
}
}
By prebuilt, I mean 3rd party libs you downloaded or a library you built using the NDK toolchain or your own ARM toolchain (not the ndk-build script itself).
In API 18, they fixed a long standing architectural issue that prevented the native lib loader from "automatically" loading dependencies because it didn't know about the application's lib directory (security reasons, etc). In API 18 and above, if myNative depends on myDependency above, you can just call loadLibrary("myNative") and the OS will handle loading myDependency. Don't RELY on this though, until the market penetration of devices running API 17 and below is at a low number acceptable to you.
To explicitly Build NDK Libraries From Source in the current version of Android Studio, you may do the following:
Set the ndk.dir value in your local.properties to point to NDK home as mentioned previously. Does anyone know if you can use env vars directly in local.properties? :)
In your build.gradle file, add something like this to your task (again, can be defaultConfig, debug, release, a productFlavor, etc):
ndk {
moduleName "myNDKModule"
stl "stlport_shared"
ldLibs "log", "z", "m"
cFlags "-I/some/include/path"
}
This is the basic structure with currently supported types (moduleName, stl, ldLibs, and cFlags). I looked and did not find more than this. There is an issue I believe with ldLibs because it automatically adds "-l" to the front of each field above. You can trick it though (I had to) by saying:
ldLibs "log -lz -lm -Wl,-whole-archive -l/path/to/someOtherLib -Wl,-no-whole-archive"
In this line, you're just tagging on to the end of the first parameter to add parameters that don't start with -l, so you can get by for now. In the case above, I'm linking a whole static library into my NDK module for use from within Java. I've asked the google developer to add additional features to allow this or even ability to merge your own Android.mk file into the NDK build process, but as this is all new, it may be a while.
Currently, whatever you put in build.gradle deletes the temp build directory and recreates it every time, so unless you want to download and modify the gradle android plugin source code (which would be fun), there are some "make due"'s like this required to get your stuff copied into the build. The android gradle script that provides this ndk support in essence generates an Android.mk file and builds using the NDK system in a temporary directory.
Sidetracked for a sec. The moduleName should match a c or cpp file in your project under the jni directory like:
[project]/[app]/src/main/jni/myNDKModule.cpp
The stl value should be set to a value of "stlport_shared" or "stlport_static" if you want to use the stlport libraries for C++. You can leave stl out if you don't need extended C++ support. Remember Android provides very basic C++ support by default. For other supported C++ libraries, view your NDK documentation guidelines in the NDK you downloaded. Note that by setting it to stlport_shared here, gradle copies the libstlport_shared.so lib from your NDK's sources/cxx-stl/stlport/libs directory to your APK's lib directories. It also handles the include path in the compiler (technically the gradle doesn't do all of this, but the Android NDK build system). So don't put your own copy of stlport into your jniLibs directory.
Lastly, I think cFlags is pretty obvious.
You can not set ANDROID_NDK_HOME on the Mac OSX (see below), but from some research I've done appears maybe this still works on other OSs. It will be removed though.
I wanted to comment but don't have the reputation yet. Dennis, the environment variables are ignored completely, not just overridden. In fact, you don't get any of your environment variables. From what I can tell, the Android Studio IDE creates its own environment with just a few specific environment variables (check System.getenv() and print it out from a gradle script).
I wrote this up as a bug here because using env vars builds fine from cmd line:
https://code.google.com/p/android/issues/detail?id=65213
but as you can see, Google decided they didn't want environment variables being used by the IDE at all; I'm still on the fence on that decision. It makes my life painful to have to update local.properties to point to absolute paths that can be loaded in my gradle scripts, which I still haven't figured out how to do yet (but haven't looked that hard). That means I either force my team members to use the same path as me, play with links, make them all type them in every time they pull the repo, or add an automation script. I believe it's a bad decision that will cost time for any developers that rely on env vars which may be small at the micro level but huge at the macro level.
groundloop, I believe the IDE will be updated soon with the ability to add the NDK folder path to your project, and it will auto generate the local.properties file from that (at least it wouldn't make sense if they had not thought of this).
For more detailed examples from Google, here are the latest examples (search for jni or ndk):
https://docs.google.com/viewer?a=v&pid=sites&srcid=YW5kcm9pZC5jb218dG9vbHN8Z3g6NDYzNTVjMjNmM2YwMjhhNA
cross-platform fat APKs using NDK:
Lastly, there is a drawback to using gradle and not being able to provide your own Android.mk file so that you could only link in 3rd party native libraries from a single architecture to your NDK. Note I said "link in". You can build the NDK Modules (moduleName above) in several architectures with the "abiFilters" command, and they will be placed in your app such that the same APK could be used on multiple architectures. If you need to link in your own 3rd party libs or even have different values for cFlags depending on your architecture, there's not a simple way.
I tried the following and it appeared to work at first, but then I found out it was simply building the NDK by appending everything together from the two ndk sections (or something like that, it did somehow build multiple architecture libraries though):
android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
versionCode 28
versionName "3.0"
}
buildTypes {
def commonLibs = " -lfoo -lbar -lwhatever"
def armV7LibsDir = "/whatever/armv7a/libs"
def armX86LibsDir = "/whatever/x86/libs"
def armV7IncDir = "/whatever/armv7a/include"
def x86IncDir = "/whatever/x86/include"
debug {
ndk {
cFlags = "-I" + armV7IncDir
moduleName "myNativeCPPModule"
stl "stlport_shared"
abiFilter "armeabi-v7a"
ldLibs "log -L" + armV7LibsDir + commonLibs
}
ndk {
cFlags = "-I" + armX86IncDir
moduleName "myNativeCPPModule"
stl "stlport_shared"
abiFilter "x86"
ldLibs "log -L" + armX86LibsDir + commonLibs
}
}
}
}
After much grief trying to create a fat binary in a clean manor with gradle and native 3rd party libs, I finally came to the conclusion that Google Play's built-in multi-architecture support for APKs is really the best route to go anyway, so create individual APKs for each architecture.
So I created multiple buildTypes, no product flavors, and added the following code to generate the version code for each type.
// This is somewhat nasty, but we need to put a "2" in front of all ARMEABI-V7A builds, a "3" in front of 64-bit ARM, etc.
// Google Play chooses the best APK based on version code, so if a device supports both X86 and
// ARM, it will choose the X86 APK (preferred because Inky ARM running on an X86 with Houdini ARM Emulator crashes in our case)
android.applicationVariants.all { variant ->
if (variant.buildType.name.equals('release')) {
variant.mergedFlavor.versionCode = 2000 + defaultConfig.versionCode
} else if (variant.buildType.name.equals('debug')) {
variant.mergedFlavor.versionCode = 2000 + defaultConfig.versionCode
} else if (variant.buildType.name.equals('debugArmV8a')) {
variant.mergedFlavor.versionCode = 3000 + defaultConfig.versionCode
} else if (variant.buildType.name.equals('releaseArmV8a')) {
variant.mergedFlavor.versionCode = 3000 + defaultConfig.versionCode
} else if (variant.buildType.name.equals('debugMips')) {
variant.mergedFlavor.versionCode = 5000 + defaultConfig.versionCode
} else if (variant.buildType.name.equals('releaseMips')) {
variant.mergedFlavor.versionCode = 5000 + defaultConfig.versionCode
} else if (variant.buildType.name.equals('debugMips64')) {
variant.mergedFlavor.versionCode = 6000 + defaultConfig.versionCode
} else if (variant.buildType.name.equals('releaseMips64')) {
variant.mergedFlavor.versionCode = 6000 + defaultConfig.versionCode
} else if (variant.buildType.name.equals('debugX86')) {
variant.mergedFlavor.versionCode = 8000 + defaultConfig.versionCode
} else if (variant.buildType.name.equals('releaseX86')) {
variant.mergedFlavor.versionCode = 8000 + defaultConfig.versionCode
} else if (variant.buildType.name.equals('debugX86_64')) {
variant.mergedFlavor.versionCode = 9000 + defaultConfig.versionCode
} else if (variant.buildType.name.equals('releaseX86_64')) {
variant.mergedFlavor.versionCode = 9000 + defaultConfig.versionCode
}
}
Now all you have to do is set the value for versionCode in your defaultConfig object, as you would do normally, and this appends it to the end of the architecture-specific version string, based on build type. The version string remains the same for all builds but varies the code to provide an order of precedence from ARM all the way up to X86_64. It's a bit hackish or hard-coded, but it gets the job done. Note that this provides you with up to 999 versions, so if you need more, multiply the numbers above by 10, not sure what the max value is that you can put in for the version code.
In my case, we have a fairly complex build system. We build CPython for 9 architectures, 3 of which are Android, then build a bunch of our own libraries, and link them all together into a single library for each architecture. We use the ndk command line build tools, automake, and python to build everything, instead of Android.mk files. The final libraries are then linked into a single JNI interface cpp file (called myNativeCPPModule above). One click of the button, and everything is built all at once, very nice Android Studio.
Found the answer. Including ndk.dir=path/to/ndk in the local.properties file did the trick.
Update:
On the latest versions of Android Studio, you can set the value directly in the Project Structure > SDK location.
you can also set ANDROID_NDK_HOME environment variable
As commented before, adding ndk.dir= in local.properties helps. Interestingly I found that local.properties overrides any value set for environment variable ANDROID_NDK_HOME, even if you don't have ndk.dir configured in local.properties. (at least with the gradle android plugin v 0.7.3).
This is confounding as Android Studio can overwrite local.properties, and it doesn't seem to provide a way to configure ndk.dir :(
Android studio suggests to include the path to ndk in local.properties

Resources