Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
plugin with Android Studio — Gideros Forum

plugin with Android Studio

timecctimecc Member
edited September 2014 in General questions
I'm a first time user.

I have been attempting to build a plugin, following the excellent example on AppCodingEasy. This is what I did:

- export the project as AppCodingEasy suggests
- import the Eclipse project into Android Studio
- add an extra empty .cpp file to get round a bug in Android Studio/gradle The build fails if there is only one source file!

My build.gradle file now looks like this
apply plugin: 'com.android.application'
android {
    compileSdkVersion 19
    buildToolsVersion "20.0.0"
 
    defaultConfig {
        applicationId "com.foo.ExamplePlugin"
        minSdkVersion 8
        targetSdkVersion 19
 
        ndk {
            moduleName "lua"
            stl        "stlport_shared"
            ldLibs     "log"
            abiFilters "armeabi", "armeabi-v7a"
        }
    }
 
    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}
 
dependencies {
    compile files('libs/gideros.jar')
}
And it nearly works ;-) The java builds OK and the cpp compiles OK. But I get a bunch of linker errors like this:
error: undefined reference to 'lua_tolstring'
error: undefined reference to 'lua_tolstring'
Here is a full error line in case it illuminates something:
E:/lingos/androidNDK/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld.exe: E:\design\android\ExamplePlugin\app\build\intermediates\ndk\debug\obj/local/armeabi/objs/lua/E_\design\android\ExamplePlugin\app\src\main\jni\ExamplePlugin.o: in function modifyString(lua_State*):ExamplePlugin.cpp(.text._ZL12modifyStringP9lua_State+0x134): error: undefined reference to 'lua_tolstring'
One possiblity is that I don't have the build set up to generate the right target. I am supposed to be generating ????

Could a guru please confirm that lua references are being linked in from gideros.so?

Any ideas?

If you read this far, thanks for reading :)

Tim

Comments

  • Unfortunately I'm not familiar with gradle config files, but is there still a jni folder with Android.mk file involved? if yes, what does your Android.mk file looks like?

    The way I saw it before is creating jni folder with Android.mk file (just like in eclipse) and then gradle should automatically call ndk-build if it finds jni folder.
  • Thanks for the message. I don't think anyone is familiar with gradle config files :)

    The directories under ...Plugin/app/src/main are aidl, assets, java, jni, jniLibs, and res. As I understand it (!) jniLibs is a relatively recent addition to the gradle world. jniLibs is the home for armeabi etc. and the shared libs.

    Here is the Android.mk file. It sits in app/src/main:
    LOCAL_PATH := $(call my-dir)
     
    ###
     
    include $(CLEAR_VARS)
     
    LOCAL_MODULE            := lua
    LOCAL_SRC_FILES         := ../../libs/$(TARGET_ARCH_ABI)/liblua.so
     
    include $(PREBUILT_SHARED_LIBRARY)
     
    ###
     
    include $(CLEAR_VARS)
     
    LOCAL_MODULE            := gvfs
    LOCAL_SRC_FILES         := ../../libs/$(TARGET_ARCH_ABI)/libgvfs.so
     
    include $(PREBUILT_SHARED_LIBRARY)
     
    #
    # Gideros Shared Library
    #
    include $(CLEAR_VARS)
     
    LOCAL_MODULE            := gideros
    LOCAL_SRC_FILES         := ../../libs/$(TARGET_ARCH_ABI)/libgideros.so
     
    include $(PREBUILT_SHARED_LIBRARY)
     
    #
    # Lua Socket Library
    #
    include $(CLEAR_VARS)
     
    LOCAL_MODULE            := luasocket
    LOCAL_SRC_FILES         := ../../libs/$(TARGET_ARCH_ABI)/libluasocket.so
     
    include $(PREBUILT_SHARED_LIBRARY)
     
    #
    # Lua File System Library
    #
    include $(CLEAR_VARS)
     
    LOCAL_MODULE            := lfs
    LOCAL_SRC_FILES         := ../../libs/$(TARGET_ARCH_ABI)/liblfs.so
     
    include $(PREBUILT_SHARED_LIBRARY)
     
    #
    # Plugin
    #
    include $(CLEAR_VARS)
     
    LOCAL_MODULE           := ExamplePlugin
    LOCAL_ARM_MODE         := arm
    LOCAL_CFLAGS           := -O2
    LOCAL_SRC_FILES        := ExamplePlugin.cpp
    LOCAL_LDLIBS             := -ldl -llog
    LOCAL_SHARED_LIBRARIES := gideros
     
    include $(BUILD_SHARED_LIBRARY)
    Here is Application.mk, from the same directory as the above:
    APP_STL := gnustl_static
    APP_CPPFLAGS += -fexceptions -frtti
    APP_PLATFORM := android-8
    APP_ABI := armeabi armeabi-v7a x86
    APP_OPTIM := release
    And here is Android.mk from /app/build/intermediates/ndk/debug
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
     
    LOCAL_MODULE := lua
    LOCAL_LDLIBS := \
    	-llog \
     
    LOCAL_SRC_FILES := \
    	E:\design\android\ExamplePlugin\app\src\main\jni\Android.mk \
    	E:\design\android\ExamplePlugin\app\src\main\jni\Application.mk \
    	E:\design\android\ExamplePlugin\app\src\main\jni\ExamplePlugin.cpp \
    	E:\design\android\ExamplePlugin\app\src\main\jni\empty.cpp \
     
    LOCAL_C_INCLUDES += E:\design\android\ExamplePlugin\app\src\main\jni
    LOCAL_C_INCLUDES += E:\design\android\ExamplePlugin\app\src\debug\jni
     
    include $(BUILD_SHARED_LIBRARY)
    Is it your sense that I could run ndk-build and somehow insert the result into the gradle world?

    Tim
  • ar2rsawseenar2rsawseen Maintainer
    edited September 2014 Accepted Answer
    Yes from this post:
    http://stackoverflow.com/a/24083451/2274511

    By default this will ignore your Android.mk and Application.mk files (thus not linking lua and other libs). As a workaround, you can tell gradle to disable atuomatic ndk-build call, then specify the directory for ndk sources manually.

    It can be done by providing jniLibs.src

    for example:

    sourceSets.main {
    jniLibs.srcDir 'src/main/libs' // use the jni .so compiled from the manual ndk-build command
    jni.srcDirs = [] //disable automatic ndk-build call
    }
    to load precompiled liblua.so, libgideros.so, etc

    You can also check other answers on that thread with some informative links
  • Thanks for that link.

    I also updated my NDK from v9 to v10, though that may not have been needed.

    After the following changes to Android.mk, ndk-build now works splendidly:
    1. change ../../libs to ../jniLibs
    2. add lua at the end: LOCAL_SHARED_LIBRARIES := gideros lua

    This builds and copies stuff from jniLibs to libs. And it ignores the empty file needed to get round a gradle bug. I then have to go into the libs directory and delete the duplicates or the Android packager complains about duplicate .so files in libs and jniLibs. There must be a way round that, but not that I could see.

    Everything builds and packages OK! And loads to a device. As usual, the plugin builds as libmyPlugin.so. Case matters! That is a mini-bug in the original AppCodingEasy article.

    BUT it doesn't run! Here is a bit of logcat:
    09-23 23:16:16.058  17096-17123/com.foo.bxPlugin E/AndroidRuntime﹕ FATAL EXCEPTION: GLThread 53583
        Process: com.foo.bxPlugin, PID: 17096
        java.lang.NoClassDefFoundError: com/giderosmobile/android/player/GiderosApplication$3
                at com.giderosmobile.android.player.GiderosApplication.finishActivity(GiderosApplication.java:856)
                at com.giderosmobile.android.player.GiderosApplication.nativeDrawFrame(Native Method)
                at com.giderosmobile.android.player.GiderosApplication.onDrawFrame(GiderosApplication.java:492)
                at com.giderosmobile.android.GiderosRenderer.onDrawFrame(bxPluginActivity.java:254)
                at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1523)
                at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
         Caused by: java.lang.NoClassDefFoundError: com/giderosmobile/android/bxPlugin
                at com.giderosmobile.android.player.GiderosApplication.nativeDrawFrame(Native Method)
                at com.giderosmobile.android.player.GiderosApplication.onDrawFrame(GiderosApplication.java:492)
                at com.giderosmobile.android.GiderosRenderer.onDrawFrame(bxPluginActivity.java:254)
                at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1523)
                at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
    Thanks for all the help
    Tim
  • Now the question is, what your plugin actually does?
    Does it have a java file to which you reference through jni?

    Did you modify activity to include both System.load and your java class in externalClasses?
  • Thanks for all the help. The plugin finally works! Chasing down the few things that had to be fixed disrupted other parts of the program. But it's all lined up now, including the mods ar2rsawseen mentions.

    So far I have only implemented a few simple functions, though separately I have developed code to use USB host mode. So now the challenge is to tie the two parts together, but that's just work ;-)

    I plan to open source the Android Studio project in a few weeks time.

    Tim
Sign In or Register to comment.