0

Since I decided to add native code to an app, I moved to Gradle Experimental plugin following this migration guide. I have successfully solved many compatibility issue due to new different syntax, but I still have problems.

The app itself works but there are two missing things that I should be able to archive with this migration:

  • Debug native code files
  • Make NDK-build process automatic, replacing Android.mk method, so it recompile needed libs when changes are made

Debug

For the first point I read that going to Edit Configurations > Debugger > Debug type = Hybrid should be enough, but I'm still not able to to perform debug of native code. This issue may be cause by the fact that I'm not configuring gradle correctly? (see below)

NDK-build

I'm trying to translate the Android.mk and putting it into Gradle build file without success. Changes to native files are not reflected when running the app because native libs haven't been rebuilt. I tried to get some advices from here.

My current Android.mk

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

MY_CHROMAPRINT_SRC_FILES := \
    ../deps/chromaprint/src/audio_processor.cpp \
    ../deps/chromaprint/src/base64.cpp \
    ../deps/chromaprint/src/chroma.cpp \
    ../deps/chromaprint/src/chroma_filter.cpp \
    ../deps/chromaprint/src/chromaprint.cpp \
    ../deps/chromaprint/src/chroma_resampler.cpp \
    ../deps/chromaprint/src/fft.cpp \
    ../deps/chromaprint/src/fft_lib_kissfft.cpp \
    ../deps/chromaprint/src/filter.cpp \
    ../deps/chromaprint/src/fingerprint_calculator.cpp \
    ../deps/chromaprint/src/fingerprint_compressor.cpp \
    ../deps/chromaprint/src/fingerprint_decompressor.cpp \
    ../deps/chromaprint/src/fingerprinter_configuration.cpp \
    ../deps/chromaprint/src/fingerprinter.cpp \
    ../deps/chromaprint/src/image_builder.cpp \
    ../deps/chromaprint/src/integral_image.cpp \
    ../deps/chromaprint/src/silence_remover.cpp \
    ../deps/chromaprint/src/spectral_centroid.cpp \
    ../deps/chromaprint/src/spectrum.cpp \
    ../deps/chromaprint/src/avresample/resample2.c

MY_KISSFFT_SRC_FILES := \
    ../deps/kissfft/kiss_fft.c \
    ../deps/kissfft/tools/kiss_fftr.c

LOCAL_MODULE := my_app_lib
LOCAL_SRC_FILES := my_app_lib.c $(MY_CHROMAPRINT_SRC_FILES) $(MY_KISSFFT_SRC_FILES)
LOCAL_CFLAGS := -DWITH_KISSFFT -DHAVE_ROUND
LOCAL_LDLIBS := -llog
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../deps/chromaprint/src $(LOCAL_PATH)/../deps/kissfft

include $(BUILD_SHARED_LIBRARY)

The build.gradle file as of now:

apply plugin: 'com.android.model.application'

def ndkDir = System.getenv("ANDROID_NDK_HOME")
def propertiesFile = project.rootProject.file('local.properties')
if (propertiesFile.exists()) {
    Properties properties = new Properties()
    properties.load(propertiesFile.newDataInputStream())
    ndkDir = properties.getProperty('ndk.dir')
}

model {
    android {

        compileSdkVersion 25
        buildToolsVersion "25.0.2"

        ndk {
            moduleName "my_app_lib"
            CFlags.add("-DWITH_KISSFFT -DHAVE_ROUND -DDEBUG_MODE=1")
            CFlags.add("-I${file("deps/chromaprint/src")}".toString())
            ldLibs.add("log")
            stl "stlport_static"
        }

        defaultConfig.with {
            applicationId "com.my_app"
            minSdkVersion.apiLevel 16
            targetSdkVersion.apiLevel 25
            versionCode 132
            versionName "1.6.108"
            vectorDrawables.useSupportLibrary = true
        }

        buildTypes {

            release {
                debuggable = false
                minifyEnabled = true
                proguardFiles.add(file("proguard-rules.pro"))
                ndk.with {
                    debuggable = true
                }
            }
            debug {
                debuggable = true
                minifyEnabled = false
                proguardFiles.add(file("proguard-rules.pro"))
                ndk.with {
                    debuggable = true
                }
            }
        }

        sources {
            main {
                java {
                    source {
                        srcDir "src"
                    }
                }
                jni {
                    source {
                        srcDirs = [ "jni" ]
                    }
                }
                jniLibs {
                    source {
                        srcDirs = [ "libs" ]
                    }
                }
            }
        }

        externalNativeBuild {
            ndkBuild {
                path 'jni/Android.mk'
            }
        }
    }
}

task buildNative(type: Exec, description: 'Compile JNI source via NDK'){
    commandLine "$ndkDir\\ndk-build.cmd",'-C', file('jni').absolutePath
}

tasks.all {
    task ->
        if (task.name.startsWith('compile') && task.name.contains('MainC')) {
            task.enabled = false
        }
        if (task.name.startsWith('link')) {
            task.enabled = false
        }
        if (task.name.endsWith('SharedLibrary') ) {
            task.dependsOn buildNative
        }
}

This is the current folder structure:

enter image description here

I'm pretty sure there's something missing in the Gradle NDK part, but I should solve the problem? I'm sorry if it will result in a dumb question, but it's the first time I'm getting into NDK and mk logics.

EDIT: I found feedbacks that report the same problem not being able to debug native code with latest NDK/AS, so we have to wait...

Community
  • 1
  • 1
fillobotto
  • 3,698
  • 5
  • 34
  • 58

1 Answers1

0

The problem was solved when I updated to Android Studio 2.3.3 along with updating project Gradle plugin to 2.3.3.

Also on Android Studio 3.0 it's still fine.

fillobotto
  • 3,698
  • 5
  • 34
  • 58