Sorry for my english...
I have last android studio (14 june 2013).
Create new Android project.
Add .so files to /libs/armeabi
Edit build.gradle to
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.4'
}
}
apply plugin: 'android'
dependencies {
compile files('libs/android-support-v4.jar','libs/jcPKCS11.jar')
}
android {
compileSdkVersion 17
buildToolsVersion "17.0.0"
defaultConfig {
minSdkVersion 14
targetSdkVersion 16
}
}
task copyNativeLibs(type: Copy) {
from(new File(project(':JaCertTest').getProjectDir(), 'libs/armeabi')) { include '**/*.so' }
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('build/native-libs')
}
I received an error:
FAILURE: Build failed with an exception.
What went wrong:
A problem was found with the configuration of task ':JaCertTest:packageDebug'.
Directory 'build\native-libs' specified for property 'jniDir' does not exist.
How it is correct to write an build script?
This will happen if your copyNativeLibs task fails to find any files, and therefore doesn't create the "build\native-libs" directory. Are you sure that there are .so files in your "libs/armeabi" directory?
Also, keep in mind that your script won't actually compile the native code. You still need to do that yourself by running ndk-build to generate the .so libraries.
Here is an example of how to get your script to compile your native code. Note, this requires that ndk-build is in your PATH.
// Task to run ndk-build
task ndkBuild(type: Exec) {
commandLine 'ndk-build', '-j', Runtime.runtime.availableProcessors()
}
task copyNativeLibs(type: Copy) {
from(new File(project(':JaCertTest').getProjectDir(), 'libs/armeabi')) { include '**/*.so' }
into new File(buildDir, 'native-libs')
}
// Make copyNativeLibs depend on ndkBuild since we must build the libraries
// before we can copy them.
copyNativeLibs.dependsOn 'ndkBuild'
tasks.withType(Compile) { compileTask -> compileTask.dependsOn copyNativeLibs }
clean.dependsOn 'cleanCopyNativeLibs'
tasks.withType(com.android.build.gradle.tasks.PackageApplication) { pkgTask ->
pkgTask.jniDir new File('build/native-libs')
}
Try this in your build.gradle:
dependencies {
// whatever you'd normally have here...
compile fileTree(dir: 'libs', include: '*.jar')
}
task packageNativeLibs(type: Jar) {
baseName 'libtest' // adjust to what you want your lib to be called
// libs is where normally a jni project puts objects so let's look there....
from(file('libs/armeabi/')) {
include '**/*.so'
}
into('libs/armeabi') // pay attention if using a different ABI like x86
destinationDir(file('libs/'))
}
tasks.withType(Compile) { compileTask -> compileTask.dependsOn packageNativeLibs }
clean.dependsOn 'cleanPackageNativeLibs'
Then you should be good
You can try this:
// Include the native-libs folder into the final APK
tasks.withType(com.android.build.gradle.tasks.PackageApplication) {
pkgTask ->
pkgTask.jniFolders = new HashSet<File>()
pkgTask.jniFolders.add(new File(buildDir, 'native-libs'))
}
Related
I have started to work on an existing project including Android NDK. I have two issues in build.gradle, which is impossible for me to build the app. For your information, my co-worker (who was working on it) was able to build the app.
I have already imported the NDK, from the project structures I can see the correct Android NDK path.
Here is how build.gradle looks like :
import org.apache.tools.ant.taskdefs.condition.Os
buildscript {
repositories {
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
// The Fabric Gradle plugin uses an open ended version to react
// quickly to Android tooling updates
classpath 'io.fabric.tools:gradle:1.21.5'
}
}
allprojects {
repositories {
maven { url "https://jitpack.io" }
}
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
apply plugin: 'realm-android'
repositories {
maven { url 'https://maven.fabric.io/public' }
}
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"
dataBinding{
enabled = true;
}
defaultConfig {
applicationId "com.lucien.myapp"
minSdkVersion 16
targetSdkVersion 24
versionCode 1
versionName "1.0.0"
ndk {
moduleName "DSPLib-jni"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets.main.jni.srcDirs = [] // disable automatic ndk-build call, which ignore our Android.mk
sourceSets.main.jniLibs.srcDir 'src/main/libs'
// call regular ndk-build(.cmd) script from app directory
task ndkBuild(type: Exec) {
workingDir file('src/main')
commandLine getNdkBuildCmd()
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
task cleanNative(type: Exec) {
workingDir file('src/main')
commandLine getNdkBuildCmd(), 'clean'
}
clean.dependsOn cleanNative
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.2.0'
compile 'com.android.support:design:24.2.0'
compile 'com.android.support:support-v4:24.2.0'
compile 'com.github.PhilJay:MPAndroidChart:v2.2.5'
compile 'com.orhanobut:dialogplus:1.11#aar'
compile('com.crashlytics.sdk.android:crashlytics:2.6.2#aar') {
transitive = true;
}
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.google.code.gson:gson:2.7'
}
def getNdkDir() {
if (System.env.ANDROID_NDK_ROOT != null)
return System.env.ANDROID_NDK_ROOT
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkdir = properties.getProperty('ndk.dir', null)
if (ndkdir == null)
throw new GradleException("NDK location not found. Define location with ndk.dir in the local.properties file or with an ANDROID_NDK_ROOT environment variable.")
return ndkdir
}
def getNdkBuildCmd() {
def ndkbuild = getNdkDir() + "/ndk-build"
if (Os.isFamily(Os.FAMILY_WINDOWS))
ndkbuild += ".cmd"
return ndkbuild
}
I have an issue with the first line, trying to import "org.apache.tools.ant.taskdefs.condition.Os" : Cannot resolve symbol 'tools'
And the same kind of issue for "throw new GradleException("...")"
Do I need to update something in my build.gradle ? Or the issue is somewhere else ?
Thanks !
You can use any other available exceptions from java like:
throw new FileNotFoundException("Could not read version.properties!")
very simple delete new from build.gradle
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
delete new
throw GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
For those who come here, I resolved my issue by going back to Android Studio 2.1. Since the release of stable version 2.2, it's working great.
You can use
throw new FileNotFoundException("Flutter SDK not found")
I'm packaging up my build artefacts from a gradle build. It's an Android Studio project.
I have tasks that successfully create a zip file containing two jars. Let's say the zip file is called 'my.zip'.
I have the following gradle task:
task renameArtifacts (type: Copy) {
from ('build/')
include 'my.zip'
destinationDir file('build/')
doLast {
println "my-${versionString}.zip"
rename('build/my.zip', "build/my-${versionString}.zip")
}
}
And I'm calling it with gradle -PversionString="123" :sdk:renameArtifacts
I have a println in the doLast closure and can see the my string interpolation is working correctly as it outputs my-123.zip.
However, 'my.zip' is not renamed to 'my-123.zip'. It remains 'my.zip' and in fact results in a file with a size of zero bytes and is no longer openable as a zip file.
I'm obviously going wrong somewhere, but where?
Full gradle file:
apply plugin: 'com.android.library'
android {
compileSdkVersion 22
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 14
targetSdkVersion 14
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:support-v4:22.2.0'
compile files('libs/urbanairship-lib-3.1.0.jar')
compile files('libs/jackson-annotations-2.2.2.jar')
compile files('libs/jackson-core-2.2.2.jar')
compile files('libs/jackson-databind-2.2.2.jar')
}
task updateVersionNumber() << {
ant.replace(file: 'src/main/java/com/my/Version.java', token: '{{VERSION}}', value: versionString)
}
task javadoc(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
destinationDir = file("build/javadoc")
failOnError false
}
task createJavaDocJar(type: Jar) {
from ('build/javadoc')
destinationDir file('build')
baseName = 'my_doc'
}
createJavaDocJar.dependsOn(javadoc)
task packageMyJarAndDependencies(type: Jar) {
from (zipTree('libs/jackson-annotations-2.2.2.jar')) {
exclude 'META-INF/maven/'
exclude 'META-INF/services/'
}
from (zipTree('libs/jackson-core-2.2.2.jar')) {
exclude 'META-INF/maven/'
exclude 'META-INF/services/'
}
from (zipTree('libs/jackson-databind-2.2.2.jar')) {
exclude 'META-INF/maven/'
exclude 'META-INF/services/'
}
from (zipTree('libs/urbanairship-lib-3.1.0.jar'))
from (zipTree('build/intermediates/bundles/release/classes.jar'))
}
task createFinalJar(type: Copy) {
from('build/libs/')
into('build')
include('sdk.jar')
rename('sdk.jar', 'my.jar')
}
createFinalJar.dependsOn(clean, build, packageMyJarAndDependencies)
packageMyJarAndDependencies.mustRunAfter build
build.mustRunAfter clean
task zipArtifacts(type: Zip) {
from ('build/')
from ('build/libs')
include 'my_doc.jar'
include 'my.jar'
baseName = 'my_lib'
destinationDir file('build')
}
zipArtifacts.dependsOn(createFinalJar, createJavaDocJar)
task renameArtifacts (type: Copy) {
from ('build/')
into('build')
include 'my_lib.zip'
doLast {
println "my_lib-${versionString}.zip"
rename "my_lib.zip", "my_lib-${versionString}.zip"
}
}
renameArtifacts.dependsOn(zipArtifacts)
rename is a method on CopyProcessingSpec, that configures the task to perform some renamings while operating. If you wrap it in doLast, the copying has already happened, and no rename will be performed. Furthermore, rename takes only file names, not relative or absolute file paths. This should work:
project.ext.versionString = versionString
task renameArtifacts (type: Copy) {
from ('build/')
include 'my.zip'
destinationDir file('build/')
rename 'my.zip', "my-${project.versionString}.zip"
}
Edit: $versionString is not accessible in tasks. Using extra project property is the suggested way how to pass these in tasks (see here).
I am developing an Video Compression app so i am using NDK and getting error when run the app.
I seen the many stackOverflow Questions (Execution error in app:buildNative) but the stackOverflow solutions are not works for this error.
Gradle Build Message:
Gradle tasks [:app:assembleDebug]
:app:buildNative FAILED
Error:Execution failed for task ':app:buildNative'.
> A problem occurred starting process 'command 'null/ndk-build.cmd''
Is anyone help for my questions?
build.gradle(Module:app)
apply plugin: 'com.android.application'
android {
compileSdkVersion 22
buildToolsVersion '22.0.1'
defaultConfig {
applicationId "com.xxxx.videocompressor"
minSdkVersion 16
targetSdkVersion 22
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
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'
}
clean.dependsOn 'cleanNative'
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn buildNative
}
productFlavors {
}
}
dependencies {
compile 'com.android.support:support-v4:22.2.+'
compile 'com.android.support:support-v4:22.2.+'
compile 'com.android.support:appcompat-v7:22.2.+'
compile 'com.android.support:recyclerview-v7:22.2.+'
compile 'com.android.support:design:22.2.+'
compile 'com.google.android.gms:play-services-ads:7.8.0'
}
Instead of using only this
// call regular ndk-build(.cmd) script from app directory
task ndkBuild(type: Exec) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
} else {
commandLine 'ndk-build', '-C', file('src/main').absolutePath
}
}
Use this
// call regular ndk-build(.cmd) script from app directory
task ndkBuild(type: Exec) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
} else {
commandLine 'ndk-build', '-C', file('src/main').absolutePath
}
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
I've started using Gradle today and after searching for an hour and trying every possible answer from SO (e.g. 1) and different blogs (e.g. 2) and documentations (e.g. 3) I need some help.
My question is simple: How to execute a custom build-step (in my case the execution of ndk-build with a customized Android.mk) as part of the regular build-process?
The build.gradle looks like this:
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.application'
android {
compileSdkVersion 19
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "myApp.prototype"
minSdkVersion 16
targetSdkVersion 19
testApplicationId "myApp.prototype.test"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
}
sourceSets.main.jni.srcDirs = []
task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
def rootDir = project.rootDir
def localProperties = new File(rootDir, "local.properties")
Properties properties = new Properties()
localProperties.withInputStream { instr ->
properties.load(instr)
}
def ndkDir = properties.getProperty('ndk.dir')
println ndkDir
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine "$ndkDir\\ndk-build.cmd",
'NDK_PROJECT_PATH=build/intermediates/ndk',
'NDK_LIBS_OUT=src/main/jniLibs',
'APP_BUILD_SCRIPT=src/main/jni/Android.mk',
'NDK_APPLICATION_MK=src/main/jni/Application.mk'
} else {
commandLine "$ndkDir/ndk-build",
'NDK_PROJECT_PATH=build/intermediates/ndk',
'NDK_LIBS_OUT=src/main/jniLibs',
'APP_BUILD_SCRIPT=src/main/jni/Android.mk',
'NDK_APPLICATION_MK=src/main/jni/Application.mk'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
compile 'com.android.support:appcompat-v7:20.+'
compile 'com.google.android.gms:play-services-location:6.5+'
compile 'com.android.support:support-v4:19.1.0'
compile 'com.google.code.gson:gson:2.2.4'
compile fileTree(dir: new File(buildDir, 'libs'), include: '*.jar')
}
When executing gradle ndkBuild from the command-line, everything works fine. But I want that Android Studio automatically runs ndkBuild when it runs the rest of the Android compile procedures (such as generateDebugSources, preBuild, preDebugBuild, ...).
I have tried to attach myself to these events like this:
gradle.projectsEvaluated {
preBuild.dependsOn(ndkBuild)
}
but regardless where I put that code, or what task I use from the variety of tasks available (when running gradle tasks), nothing seems to work.
Have you tried adding a dependency for ndkBuild on JavaCompile tasks ?
android {
...
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
}
I found this gradle script built for android studio to allow the use of the NDK until the team can create an official (and more understandable) way of accomplishing this. I don't really understand how it works or how it ties in to a normal gradle script as I am still new to this IDE. Can anybody explain it to me?
The script is:
//////////////
// NDK Support
//////////////
// If using this, Android studio will fail run the following to set the environment
// variable for android studio:
// launchctl setenv ANDROID_NDK_HOME
// /Users/boos_patrick/Development/Android/android-ndk-r8e
// otherwise remove the dependsOn part and run ./gradlew buildNative from the
// command line
task copyNativeLibs(type: Copy, dependsOn: 'buildNative') {
dependsOn 'buildNative'
from(new File('libs')) { include '**/*.so' }
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')
}
task buildNative(type: Exec) {
if (System.env.ANDROID_NDK_HOME != null) {
def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build')
commandLine ndkBuild
} else {
doLast {
println '##################'
println 'Skipping NDK build'
println 'Reason: ANDROID_NDK_HOME not set.'
println '##################'
}
}
}