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.
Related
I have .cmd file that I want to include everytime build.gradle is run by Android Studio.
Let's say the filename is create-artifacts.cmd and so in my module's build.gradle.
android {
...
task createArtifacts(type:Exec) {
commandLine = ["create-artifacts.cmd"]
workingDir = file("$rootDir")
}
}
How may I be helped with this?
See the ExecTask documentation
task createArtifacts(type:Exec) {
commandLine 'cmd', '/c', 'create-artifacts.cmd'
workingDir rootDir
}
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 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 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'