Compile NDK with gradle experimental plugin - android

I'm trying to use Experimental Gradle Plugin for my NDK projects, but it do not compile ndk. Everything looks fine - Android Studio understands my C code, can jump from Java to native and so on, but when i run "Build", step of compiling ndk is skipped - i see no tasks like "compileNdk".
When I list all available tasks by
gradlew tasks
there is no taks like "compileNdk" also. "Libs" folder are empty too, so when I try to call native method, app crash with "UnsatisfiedLinkError".
So what am i missing? How to tell gradle to compile NDK?
My config is:
root build.gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.3.0-alpha5'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
module build.gradle:
apply plugin: 'com.android.model.application'
model
{
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.1"
defaultConfig.with {
applicationId = "com.kaspersky.experimentalcpp"
minSdkVersion.apiLevel = 14
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
}
android.buildTypes {
debug {
ndk.with {
debuggable = true
}
}
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.pro')
}
}
android.sources {
main {
jni {
source {
srcDirs 'src/main/jni'
}
}
}
}
android.ndk {
moduleName = "test_experimental"
stl = "stlport_static"
cppFlags += "-Isrc/main/jni".toString()
ldLibs += ["log"]
ldLibs += ["android"]
}
android.productFlavors {
create("arm") {
ndk.abiFilters += "armeabi"
}
create("arm7") {
ndk.abiFilters += "armeabi-v7a"
}
create("fat")
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.0'
}
I'm using Android Studio 1.4.1 on Windows 7. ndk.dir points to "ndk-bundle" folder which was downloaded by AS.
Any help appreciated!

So after some research I figured out that my libs actually compiles, they just puts not in the "libs" folder, but in "build/intermediates/binaries/...". I dump result .so and figured that my JNI methods was not in there. The reason was that my JNI methods was declared in .h file. After renaming .h to .cpp all works fine (except debugging). Maybe it will help somebody else!

Related

Plugin with id 'com.android.model.native' not found

I am trying to develop a module from my C project with Android Studio. I am having the problem of
Plugin with id 'com.android.model.native' not found.
What did I do wrong?
Thank you!
Below is the App level build.gradle
apply plugin: "com.android.model.native"
model {
android {
compileSdkVersion 27
defaultConfig {
applicationId = 'com.example.androidthings.nativepio'
minSdkVersion 27
targetSdkVersion 27
versionCode 1
versionName "1.0"
}
ndk {
//platformVersion = "21"
moduleName "libusb"
ldLibs.addAll(["log"])
CFlags.add("-Wall")
CFlags.add("-I" + file("src/main/jni/android").absolutePath)
CFlags.add("-O3")
}
sources {
main {
jni {
exportedHeaders {
srcDir "src/main/jni/libusb"
}
dependencies {
project ":dependency_module"
}
}
}
}
}
}
Here is the project level build gradle
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
This plugin was part of an experimental and old version of the current build system.
You should rewrite your gradle file to work with the current build system. Either let Android Studio generate the necessary additions by linking to your CMake file, or copy from a known-good sample like the HelloJNI sample:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
ndkVersion '21.2.6472646'
defaultConfig {
applicationId 'com.example.hellojni'
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
}
buildFeatures {
viewBinding true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
}
}
flavorDimensions 'cpuArch'
productFlavors {
arm8 {
dimension 'cpuArch'
ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a'
}
}
x86_64 {
dimension 'cpuArch'
ndk {
abiFilters 'x86_64', 'x86'
}
}
universal {
dimension 'cpuArch'
// include all default ABIs. with NDK-r16, it is:
// armeabi-v7a, arm64-v8a, x86, x86_64
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

build gradle fail with "no signature of method .... is applicable for argument types: (java.lang.String) values"

I have 4 gradle build files: when I build in android studio I am constantly having the error:
No signature of method:
org.gradle.model.ModelMap.getDefaultProguardFile() is applicable for
argument types: (java.lang.String) values: [proguard-android.txt]
file 1
// 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-experimental:0.9.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
file 2
apply plugin: 'com.android.model.native'
model {
android {
compileSdkVersion = 25
buildToolsVersion = '25.0.0'
defaultConfig {
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 25
versionCode = 1
versionName = '1.0'
}
ndk {
moduleName = 'fpextractor'
platformVersion = 17
toolchain = "clang"
stl = 'gnustl_static' //std::mutex not in gnustl_static
cppFlags.add('-std=c++11')
abiFilters.addAll(['armeabi', 'armeabi-v7a', 'x86'])
//abiFilters.addAll(['armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64']) //this is default
//abiFilters.addAll(['armeabi'])
ldLibs.addAll(['android', 'log', 'atomic', 'z'])
}
}
}
// This is just copy out the header file and built lib into distribution
// directory for clint application to use; it is a small overhead of this sample:
// both lib and app are put inside one project space [save maintenance time]
task(distributeLib, type : Copy) {
// trigger build library
dependsOn assemble
into '../distribution/fpextractor/'
from('src/main/jni/fp_extractor.h') {
into 'include/'
}
from('build/outputs/native/release/lib') {
into 'lib/'
}
}
file 3
apply plugin: 'com.android.model.native'
model {
android {
compileSdkVersion = 25
buildToolsVersion = '25.0.0'
defaultConfig {
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 25
versionCode = 1
versionName = '1.0'
}
ndk {
moduleName = 'nativeaudio'
platformVersion = 17
toolchain = "clang"
stl = 'gnustl_static' //std::mutex not in gnustl_static
cppFlags.add('-std=c++11')
abiFilters.addAll(['armeabi', 'armeabi-v7a', 'x86'])
//abiFilters.addAll(['armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64']) //this is default
//abiFilters.addAll(['armeabi-v7a'])
ldLibs.addAll(['android', 'log', 'OpenSLES', 'atomic'])
}
}
}
// This is just copy out the header file and built lib into distribution
// directory for clint application to use; it is a small overhead of this sample:
// both lib and app are put inside one project space [save maintenance time]
task(distributeLib, type : Copy) {
// trigger build library
dependsOn assemble
into '../distribution/nativeaudio/'
from('src/main/jni/buf_manager.h') {
into 'include/'
}
from('src/main/jni/android_debug.h') {
into 'include/'
}
from('src/main/jni/debug_utils.h') {
into 'include/'
}
from('src/main/jni/audio_common.h') {
into 'include/'
}
from('src/main/jni/audio_recorder.h') {
into 'include/'
}
from('build/outputs/native/release/lib') {
into 'lib/'
}
}
file 4
apply plugin: 'com.android.model.application'
// Root of 3rd party lib(s): location could be anywhere on the host system
def lib_distribution_root = '../distribution'
model {
repositories {
libs(PrebuiltLibraries) {
// Configure one pre-built lib: shared
nativeaudio {
// Inform Android Studio where header file dir for this lib
headers.srcDir "${lib_distribution_root}/nativeaudio/include"
// Inform Android Studio where lib is -- each ABI should have a lib file
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("${lib_distribution_root}/nativeaudio/lib/${targetPlatform.getName()}/libnativeaudio.so")
}
}
fpextractor {
// Inform Android Studio where header file dir for this lib
headers.srcDir "${lib_distribution_root}/fpextractor/include"
// Inform Android Studio where lib is -- each ABI should have a lib file
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("${lib_distribution_root}/fpextractor/lib/${targetPlatform.getName()}/libfpextractor.so")
}
}
// Configure another pre-built lib: shared;[change to static after Studio supports]
// static lib generation. USING static lib is supported NOW, for that case,
// simple change:
// SharedLibaryBinary --> StaticLibraryBinary
// sharedLibraryFile --> staticLibraryFile
// *.so --> *.a
//gperf {
// headers.srcDir "${lib_distribution_root}/gperf/include"
// binaries.withType(SharedLibraryBinary) {
// sharedLibraryFile = file("${lib_distribution_root}/gperf/lib/${targetPlatform.getName()}/libgperf.so")
// }
//}
}
}
android {
compileSdkVersion = 25
buildToolsVersion = '25.0.0'
defaultConfig {
applicationId='com.gfk.mediawatchapp'
minSdkVersion.apiLevel = 17
targetSdkVersion.apiLevel = 25
versionCode = 22
versionName = '255.0.4'
// Enabling multidex support.
//multiDexEnabled true
}
ndk {
platformVersion = 17
moduleName = 'mwlib'
toolchain = "clang"
stl = 'gnustl_static'
cppFlags.add('-std=c++11')
ldLibs.addAll(['android', 'log', 'OpenSLES', 'atomic'])
//build a default combined apk including all ABIs.
//abiFilters.addAll(['armeabi-v7a'])
abiFilters.addAll(['armeabi', 'armeabi-v7a', 'x86']) //this is default
}
sources {
main {
jni {
dependencies {
library 'nativeaudio' linkage 'shared'
library 'fpextractor' linkage 'shared'
// if gperf were *.a, change shared --> static
//library 'gperf' linkage 'shared'
}
}
jniLibs {
// for shared lib, lib need to be pushed to the target too
// Once libs are copied into app/src/main/jniLibs directory,
// Android Studio will pack them into APK's lib/ directory
// Here we like to avoid another duplication by pointing
// to the files that containing our libs' distribution location
// so the same file is used by compiler at host, also packed
// into APk to be used at Target (phone/tablet)
source {
srcDir "${lib_distribution_root}/nativeaudio/lib"
srcDir "${lib_distribution_root}/fpextractor/lib"
//srcDir "${lib_distribution_root}/gperf/lib"
}
}
}
}
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles.add(file('proguard-android.txt'))
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
}
dependencies {
println rootProject.getName()
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:support-v4:25.3.1'
compile 'commons-net:commons-net:3.5'
//compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.android.support:cardview-v7:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.google.android.gms:play-services-appindexing:9.8.0'
compile 'com.amazonaws:aws-android-sdk-core:2.4.2'
compile 'com.amazonaws:aws-android-sdk-s3:2.4.2'
compile 'com.amazonaws:aws-android-sdk-ddb:2.4.2'
compile 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.4.2'
}
// Unnecessary dependency management:
// Make sure the libs are available when begin compiling application project
// This could be ignored because in real scenario, the pre-built libs are
// already given to us before creating application.
tasks.whenTaskAdded { task ->
if (task.name.contains('compile')) {
task.dependsOn ':nativeaudio:distributeLib'
task.dependsOn ':fpextractor:distributeLib'
}
}
Please: Can anyone help me to understand why I have always the following error:
No signature of method:
org.gradle.model.ModelMap.getDefaultProguardFile() is applicable for
argument types: (java.lang.String) values: [proguard-android.txt]
Gradle experimental does not include getDefaultProguardFile() since it does not have any version of ProGuard config by default.
You can use move the lines from your proguard-android.txt to proguard-rules.pro and then change this line:
proguardFiles.add(file('proguard-android.txt'))
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
into this:
proguardFiles.add(file('proguard-rules.pro'))
For me adding a manifest with
jar {
manifest {
attributes 'Main-Class': com.package.to.main.Class
}
}
helped.
See here: Creating runnable JAR with Gradle

Using prebuilt native .so library from java in Android Studio using experimental gradle plugin

I have added 2 .so prebuilt libraries to a new project in Android Studio which is using the experimental gradle plugin (com.android.tools.build:gradle-experimental:0.6.0-beta5).
My build.gradle file looks like this:
apply plugin: 'com.android.model.application'
model {
repositories {
prebuilt(PrebuiltLibraries) {
gstplayer {
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("libs/libgstplayer.so")
sharedLibraryFile = file("libs/libgstreamer_android.so")
}
}
}
}
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.myexample.gstreamertest2"
minSdkVersion.apiLevel 19
targetSdkVersion.apiLevel 23
versionCode 1
versionName "1.0"
buildConfigFields {
create() {
type "int"
name "VALUE"
value "1"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles.add(file('proguard-rules.pro'))
}
}
ndk {
moduleName "gstplayer"
}
productFlavors {
create("flavor1") {
applicationId "com.app"
}
}
// Configures source set directory.
sources {
main {
// jni {
// source {
// srcDirs = ['src/main/jni']
// }
// }
jniLibs {
dependencies {
library "gstplayer"
}
}
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
}
Gradle build is successful, but I can't find instructions anywhere on how to reference these libraries. I know that you can create public native String getInfoFromJni() in your Java file and reference native .c files in your jni folder, and I have been able to get this working, but I don't know how to do something similar with .so libraries.
How do I access the methods in the .so libraries from java?
You should create a wraper c lib:
1.- Change the name of the moduleName to avoid conflicts:
ndk {
moduleName "gstplayerwrapper"
}
2.- Load your wrapper lib in your activity
static{
System.loadLibrary("EcoLogSIL");
}
3.- Built your project
4.- Create a function which call the wrapper and press alt+intro
5.- You should have a new function inside gtsplayerwrapper.c and here you can call libgstplayer.so
JNIEXPORT void JNICALL
Java_your_activty_name_call_1wrapper(JNIEnv *env, jobject instance) {
// YOUR CODE HERE
}
Don't forget to import the library inside gtsplayerwrapper.c
EDIT add headers
repositories {
prebuilt(PrebuiltLibraries) {
gstplayer {
headers.srcDir "src/main/jni/include"
binaries.withType(SharedLibraryBinary) {
sharedLibraryFile = file("libs/libgstplayer.so")
sharedLibraryFile = file("libs/libgstreamer_android.so")
}
}
}
}
Create this folder in your project and copy there .h files

preBuild dependency in new experimental Gradle for NDK on Android Studio

Recently i decided to take the new NDK plugin in Android Studio for a ride
The changes needed are explained here
My build.gradle was ported successfully. Today i decided that i need a copy task in order to copy files into my 'asset' folder.
Searching online says that i must use a 'preBuild.dependsOn taskName' line, which i am sure works Ok for normal Gradle, but fails in the new experimental one (With the introduction of the 'model' behaviour)
Now my build.gradle fails.
Error:(25, 0) Could not find property 'preBuild' on root project 'Android'.
I am sure that the task is defined correctly, since the error comes from the preBuild... line
Here is my build.gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle-experimental:0.2.0'
}
}
allprojects {
repositories {
jcenter()
}
}
apply plugin: 'com.android.model.application'
task copyWebViewAssets(type: Copy){
from '../Common/WebView'
into 'src/main/assets'
include('**/*')
}
preBuild.dependsOn copyWebViewAssets
model {
compileOptions.with {
sourceCompatibility=JavaVersion.VERSION_1_7
targetCompatibility=JavaVersion.VERSION_1_7
}
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.1"
defaultConfig.with {
applicationId = "com.company.product"
minSdkVersion.apiLevel = 9
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
}
android.ndk {
moduleName = "native"
}
android.buildTypes {
release {
minifyEnabled = false
}
debug {
ndk.with {
debuggable = true
}
}
}
android.productFlavors {
// To include all cpu architectures, leaves abiFilters empty
create("all")
}
}
dependencies {
compile 'com.android.support:appcompat-v7:23.0.1'
}
I would like to address again that this is related to the new experimental Gradle for NDK. I am currently on Android Studio 1.4, using Gradle 2.5.
Thank you for your support
Use compileTask instead of prebuild
it works for me.
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn(changeNamespace)
}

Android experimental grade plugin won't see my library module

I'm compiling an Android library (.aar) as a module that contains some native code and requires some libraries. Here's the build.gradle:
apply plugin: 'com.android.model.library'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.1"
defaultConfig.with {
//
// NOTE: change the application ID to match the play console linked application.
//
applicationId = "org.anima.mrubybridge"
minSdkVersion.apiLevel = 18
targetSdkVersion.apiLevel = 18
}
}
android.ndk {
moduleName = "mrubybridge"
CFlags += "-I/home/dragos/Downloads/mruby-1.1.0/include"
CFlags += "-I/home/dragos/Downloads/mruby-1.1.0/include"
ldLibs += ["mruby"]
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.txt')
}
}
android.productFlavors {
create ("arm7") {
ndk.abiFilters += "armeabi-v7a"
ndk.ldFlags += "-L/home/dragos/Downloads/mruby-1.1.0/build/armeabi-v7a/lib"
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
This compiles everything (I checked the .class and .so files), but the .aar archives are almost empty with no classes or dynamic libraries. (about 2.3KB)
In the second module, I add this as a dependency:
apply plugin: 'com.android.model.application'
model {
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.1"
defaultConfig.with {
//
// NOTE: change the application ID to match the play console linked application.
//
applicationId = "com.example.dragos.mrubytest"
minSdkVersion.apiLevel = 18
targetSdkVersion.apiLevel = 18
}
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles += file('proguard-rules.txt')
}
}
}
dependencies {
compile project(':mrubybridge')
compile fileTree(dir: 'libs', include: ['*.jar'])
// testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
}
But when I try to add the Java classes from the other module, I get: Error:(12, 29) error: package org.anima.mrubybridge does not exist, most probably because they're not in the .aar.
I've added the module as a dependency (compile project(':mrubybridge')), but it doesn't really help.
I encountered the same issue. This answer solved it for me:
#Radix
"Put the .aar file in the app libs directory (create it if needed), then, add the following code in your app build.gradle":
dependencies {
compile(name:'nameOfYourAARFileWithoutExtension', ext:'aar')
}
repositories{
flatDir{
dirs 'libs'
}
}
Adding local .aar files to Gradle build using "flatDirs" is not working

Categories

Resources