I am trying to build android project with imported c-libraries and get next error.
Error:Execution failed for task ':app:compileDebugNdk'.
com.android.ide.common.internal.LoggedErrorException: Failed to run command:
/Applications/Android Studio.app/ndk/ndk-build NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=/Users/eugene/KREF14001/app/build/ndk/debug/Android.mk APP_PLATFORM=android-19 NDK_OUT=/Users/eugene/KREF14001/app/build/ndk/debug/obj NDK_LIBS_OUT=/Users/eugene/KREF14001/app/build/ndk/debug/lib APP_ABI=all
Error Code:
2
Output:
usage: dirname path
/Users/eugene/build/core/init.mk:471: * Android NDK: Aborting . Stop.
What does it mean? How can i fix this problem?
I've read that the NDK_HOME shouldn't contain any space in its path (even if it's \ escaped).
This is the code i use to build using android-ndk from gradle. For this add ndk directory path in gradle.properties ie . add ndkdir=/home/user/android-ndk-r9d and put all jni files in a folder native in src/main/ as you can see from code posted below. It will create jar with native libs which you can use normally as in System.loadLibrary("library");
dependencies {
compile fileTree(dir: "$buildDir/native-libs", include: '*.jar')
}
task ndkBuild(type: Exec) {
commandLine "$ndkdir/ndk-build", "--directory", "$projectDir/src/main/native", '-j', Runtime.runtime.availableProcessors(),
"APP_PLATFORM=android-8",
"APP_BUILD_SCRIPT=$projectDir/src/main/native/Android.mk",
"NDK_OUT=$buildDir/native/obj",
"NDK_APP_DST_DIR=$buildDir/native/libs/\$(TARGET_ARCH_ABI)"
}
task nativeLibsToJar(type: Zip, description: 'create a jar with native libs') {
destinationDir file("$buildDir/native-libs")
baseName 'native-libs'
extension 'jar'
from fileTree(dir: "$buildDir/native/libs", include: '**/*.so')
into 'lib/'
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn nativeLibsToJar
}
nativeLibsToJar.dependsOn 'ndkBuild'
Related
I'm developing an Android app using FFmpeg. I have built FFmpeg into *.so files and put them into jniLibs as follows:
src
--main
----jniLibs
------armeabi
--------libavcodec-57.so
--------libavformat-57.so
--------xx.so
While in grade script, abifilter of ndk is armeabi.
In java files, I have succeeded load these .so files and the built apk also contains them. However, when I use any API (e.g. av_register_all()) of them in a .c file under src/jni folder, build error comes:
Error:(14) undefined reference to 'av_register_all'
Error:Execution failed for task ':app:compileDebugNdk'.
com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Users/zhouyf/Library/Android/sdk/ndk-bundle/ndk-build'' finished with non-zero exit value 2
It seems that problem exists in linker. But I found answer that just putting .so files to jniLibs/armeabi will be OK.
Do I need modify build.gradle file to link those .so files or else?
P.S.
If I don't call the API, the app will run successfully, only with warning: W/linker: libavformat-57.so: unused DT entry: type 0x6ffffffe arg 0x60e0
W/linker: libavformat-57.so: unused DT entry: type 0x6fffffff arg 0x2
Environment:
Android Studio 2.1.1
Mac OS X 10.11.5
You should add libraries as dependencies when you build by using ndk-build.
Disable default ndk-build, in your build.gradle
sourceSets.main {
jniLibs.srcDir 'src/main/libs'
jni.srcDirs = []
}
Add your own ndk-build task, in your build.gradle
def ndkDir = properties.getProperty("ndk.dir")
task ndkBuild(type: Exec) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine ndkDir + File.separator + 'ndk-build.cmd', '-C', file('src/main/jni').absolutePath
} else {
commandLine ndkDir + File.separator + 'ndk-build', '-C', file('src/main/jni').absolutePath
}
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
Finally, in your Android.mk, add the libraries like this.
LOCAL_MODULE := # ...
# ...
LOCAL_LDFLAGS += -L/path/of/the/libraries -lavcodec-57 -lavformat-57 ...
I'm currently working on a nbk project for android. I have the current commands in my build.gradle, so that I can build from my gradle wrapper:
def ndkDir = "/Development/android-sdk-macosx/ndk-bundle"
task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
commandLine "$ndkDir/ndk-build",
'-C', file('src/main/jni').absolutePath,
'-j', Runtime.runtime.availableProcessors(),
'all',
'NDK_DEBUG=1'
}
task cleanNative(type: Exec, description: 'Clean JNI object files') {
commandLine "$ndkDir/ndk-build",
'-C', file('src/main/jni').absolutePath,
'clean'
}
I am able to build using ./gradlew buildNative, but when I try gradle assembleDebug I get errors:
compiling TextRenderer.cpp failed.
/Users/user/android-ndk/san-angeles/app/src/main/jni/src/Renderers/TextRenderer.cpp:5:10: fatal error: 'ft2build.h' file not found
#include <ft2build.h>
^
1 error generated.
compiling BoxRenderer.cpp successful.
compiling triangle.cpp successful.
Finished compileSanangelesArmeabi-v7aDebugSharedLibrarySanangelesMainCpp, see full log file:///Users/user/android-ndk/san-angeles/app/build/tmp/compileSanangelesArmeabi-v7aDebugSharedLibrarySanangelesMainCpp/output.txt.
I am using a freetype library that I cross compiled with issues, but I got it passed that point (I think):
Was able to cross compile Freetype2, now what?
Edit:
I have changed my gradle build to this:
apply plugin: 'com.android.model.application'
model {
android {
...
sourceSets.main {
jniLibs.srcDir 'src/main/jni/freetype/lib'
jni.srcDirs = []
}
...
}
}
task buildNative (...){
...
}
task cleanNative (...){
...
}
But now I get this error:
Gradle sync failed: Cause: com.android.build.gradle.managed.AndroidConfig$Impl
If you don't want to struggle with the ever-changing C++ support of the experimental gradle plugin, you can simply use build.gradle generated by Android Studio. To disable automatic compilation of C++ files in the jni folder, you can override jni.srcDirs:
jni.srcDirs = []
jniLibs.srcDir 'src/main/jni/freetype/lib'
Here I override jniLibs.srcDir so that the library compiled with ndk-build will be included in the APK file.
Actually, I prefer to keep jni.srcDirs pointing at my C++ files (this way, I don't need another IDE running to work with them), and I disable the gradle tasks (somewhere in build.gradle file):
tasks.all {
task -> if (task.name.contains('compileDebugNdk') ||
task.name.contains('compileReleaseNdk'))
task.enabled = false
}
I can also teach the system to run buildNative and cleanNative when necessary:
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn buildNative
}
clean.dependsOn cleanNative
Note that the next version of Android Studio, 2.2 (now in public beta), makes ndk-build a first class citizen.
I am using Almalence: Open Camera repository
Checkout the Screenshot
Gives Compile Errors:
Error:(24, 34) ImageConversionUtils.h: No such file or directory
compilation terminated.
make.exe: *** [C:\Users\sagar_000\Documents\OpenCamera-master\app\build\intermediates\ndk\debug\obj/local/arm64-v8a/objs/OpenCamera-master/C_\Users\sagar_000\Documents\OpenCamera-master\app\src\main\jni\bestshot\bestshot.o] Error 1
Error:Execution failed for task ':app:compileDebugNdk'.
com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'C:\Users\sagar_000\AppData\Local\Android\sdk\ndk-bundle\ndk-build.cmd'' finished with non-zero exit value 2
You just need to add these ndk properties into your build.gradle. Must be same level with defaultConfig
sourceSets.main {
jni.srcDirs = [] // This prevents the auto generation of Android.mk
jniLibs.srcDir 'src/main/libs' // This is not necessary unless you have precompiled libraries in your project.
}
task buildNative(type: Exec, description: 'Compile JNI source via NDK') {
def ndkDir = android.ndkDirectory
commandLine "$ndkDir/ndk-build.cmd",
'-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
'-j', Runtime.runtime.availableProcessors(),
'all',
'NDK_DEBUG=1'
}
task cleanNative(type: Exec, description: 'Clean JNI object files') {
def ndkDir = android.ndkDirectory
commandLine "$ndkDir/ndk-build.cmd",
'-C', file('src/main/jni').absolutePath, // Change src/main/jni the relative path to your jni source
'clean'
}
I have created following ndk task for building native component.
task clean(type: Delete) {
delete rootProject.buildDir}
task ndkBuild(type: Exec) {
println "hello 1"
commandLine 'ndk-path/ndk-build', 'NDK_PROJECT_PATH=project path'
println "hello 2"}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild}
Now when I call "./gradlew ndk-build" then .so is created under libs folder. But when I do "./gradlew assembleDebug" or "./gradlew build" then I get folowing outputs
hello 1
hello 2
But .so is not created. What is the problem?
I want to integrate Zbar into my application but cant seem to figure out how to accomplish this using the new Android Studio.
I have looked through the example and have copied over the code without any issues. The problem I am having is adding the libs to my project I cant seem to figure out how to do it. Could someone walk me through it?
I'm not particularly familiar with IntelliJ or Gradle but I have figured it out. I used ZBarAndroidSDK-0.2.
Copy the contents of the ZBar SDK libs/ folder into your project's libs/ folder.
Modify your build.gradle (see below) to make sure the jar and native libs are included in your APK.
To make IntelliJ aware of ZBar, add zbar.jar in your project structure. To do this, go to File > Project Structure > Libraries > + Sign > Java and find zbar.jar with the file picker. Add it to your project.
Add the following to your build.gradle (making sure to keep whatever other dependencies you've got):
dependencies {
compile files('libs/android-support-v4.jar')
compile files('libs/zbar.jar')
}
task copyNativeLibs(type: Copy) {
from(new File('libs')) { include '**' }
into new File(buildDir, 'native-libs')
}
tasks.withType(Compile) { compileTask -> compileTask.dependsOn copyNativeLibs }
clean.dependsOn 'cleanCopyNativeLibs'
tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask ->
pkgTask.jniDir new File(buildDir, 'native-libs')
}
My build.gradle is based on this gist: https://gist.github.com/khernyo/4226923.
Actually, #Michael's answer is correct, it is also obsolete. Now, using gradle all you need to do is to add the lines below in the build.gradle file:
android {
...
sourceSets {
main.jniLibs.srcDirs = ['libs']
test.jniLibs.srcDirs = ['libs']
}
}
or directly put your .so libraries into:
src/main/jniLibs
This way, when you build your application or library, the jni libraries are being copied into destination .jar/.aar file.
If your using gradle 1.1.0 then you must do some modifications to #Michael's answer.
Here is the revised code of gradle file which works for me.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
compile files('libs/zbar.jar')
}
task copyNativeLibs(type: Copy) {
from(new File('libs')) { include '**' }
into new File(buildDir, 'native-libs')
}
tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn copyNativeLibs }
clean.dependsOn 'cleanCopyNativeLibs'
tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask ->
pkgTask.jniFolders = new HashSet<File>()
pkgTask.jniFolders.add(new File(buildDir, 'native-libs'))
}
I've built ZBarAndroidSDK-0.2 example in Android Studio 2.0 by just opening CameraTest project from example folder.
It restructured the project from eclipse to Android Studio automatically. That is it.