10

I am trying to run a demo application of a Library in which android ndk is integrated. I have imported this code in Android studio and also downloaded ndk and linked it with project. Code compiles and build succesfully. It gives crash with exception "exception ljava lang unsatisfiedlinkerror thrown while initializing" "failed: dlopen failed: cannot locate symbol "_ZN7Tangram11setPositionEdd" referenced by "libtangram.so"..."

Application.mk:

APP_STL := c++_shared
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi armeabi-v7a x86 mips
APP_PLATFORM := android-19

Android.mk:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := tangram
LOCAL_SRC_FILES := jniExports.cpp jniGenerated.cpp platform_android.cpp
LOCAL_LDLIBS    := -llog
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
include $(BUILD_SHARED_LIBRARY)

Module Gradle File:

buildscript {
  dependencies {
    classpath 'com.android.tools.build:gradle:1.2.3'
    classpath 'com.github.dcendents:android-maven-plugin:1.2'
  }
}

apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'

group = GROUP
version = VERSION_NAME

android {
  compileSdkVersion 22
  buildToolsVersion "21.1.2"

  defaultConfig {
    minSdkVersion 15
    targetSdkVersion 22
 }

   sourceSets.main {
    manifest.srcFile 'AndroidManifest.xml'
    java.srcDirs = ['src']
    jni.srcDirs = []
    assets.srcDirs = ['core/resources']
  }

  task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
        commandLine "C:/Users/Administrator/AppData/Local/Android/android-ndk-r10e/ndk-build.cmd",
        'NDK_PROJECT_PATH=build/intermediates/ndk',
        'NDK_LIBS_OUT=jniLibs',
        'APP_BUILD_SCRIPT=jni/Android.mk',
        'NDK_APPLICATION_MK=jni/Application.mk'
  }
  tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
  }
}

// Add gdb server to apk
afterEvaluate {
    Sync packageTask =     project.getTasks().findByName("packageReleaseJniLibs")
        if (packageTask) { packageTask.include(['**/gdbserver',       '**/gdb.setup'])     }

    packageTask = project.getTasks().findByName("packageDebugJniLibs")
    if (packageTask) { packageTask.include(['**/gdbserver', '**/gdb.setup'])         }
    }

dependencies {
  compile 'com.squareup.okhttp:okhttp:2.5.0'
  compile 'xmlpull:xmlpull:1.1.3.1'
}

apply from: file('gradle-mvn-push.gradle')

In Java class load libraries:

static {
        System.loadLibrary("c++_shared");
        System.loadLibrary("tangram");
    }

I google this issue and in these posts Link1 Link2 Link3 Link4 it is mentioned that it may be the issue of compiling at api 21 or newer and running it on older devices. But i have mentioend APP_PLATFORM := android-19 in my Application.mk and getting this exception.

Any Help?

Community
  • 1
  • 1
Nouman Bhatti
  • 1,777
  • 4
  • 28
  • 55
  • Please post your code, e.g. makefile, etc. – Mine Mar 02 '16 at 09:09
  • I've seen this issue come up a few times - once because the system was trying to use its own version of the library (like in your Link2) and once because I was using code compiled with a different version of the NDK than the native code in my application. Have you used the nm tool (included in the NDK) to check if the symbol is actually exported by libtangram.so? This post might help you with that: http://stackoverflow.com/questions/23044815/compiling-c-library-for-android-but-no-symbols-found – Francesca Nannizzi Mar 08 '16 at 13:46
  • Why do you have `LOCAL_ALLOW_UNDEFINED_SYMBOLS := true` in your Android.mk file? – odexcide Mar 08 '16 at 20:51
  • @odexcide because if i dont set it to true it gives me a lot of errors of undefined symbols – Nouman Bhatti Mar 09 '16 at 05:14
  • @bullsy i think that first scenario (Link2) cant be true because system could not have its own version of tangram library or are you talking about c++_shared? In case of second scenario should i use another version of ndk and how to find in which version my native code was compiled? – Nouman Bhatti Mar 09 '16 at 05:30
  • 1
    @NoumanBhatti If you're seeing undefined symbol errors without LOCAL_ALLOW_UNDEFINED_SYMBOLS := true, there's a good chance that this symbol is one of the undefined ones. – Francesca Nannizzi Mar 09 '16 at 14:18
  • @NoumanBhatti You're using this [Tangram](https://github.com/tangrams/tangram-es) library, right? Do you have sources for Tangram? Are you using a prebuilt library? – Francesca Nannizzi Mar 09 '16 at 14:29

1 Answers1

3

It looks like you tried to compile the tangram project from your own custom ndk-build as opposed to their recommended build process (https://github.com/tangrams/tangram-es#android). Use their build process with make to create the libtangram.so file, and then copy that .so file into your native libraries directory for your app.

The reason it can't find those symbols is because you aren't including the appropriate source files that define those functions when building with the ndk. By ingnoring undefined symbols, it will compile but won't be able to resolve them at runtime.

The symbol you are missing is created from Tangram::setPosition(double, double) which is defined at https://github.com/tangrams/tangram-es/blob/master/core/src/tangram.cpp#L318 ; however, your Android.mk file doesn't include that source file.

odexcide
  • 682
  • 3
  • 7