Help me to launch the "Box2D helloworld project" on Android !!! Lost in Android.mk files ! :(

Hi !

As I wanted to play with Android NDK, JNI, Android.mk files, etc…, this week was the worst of my developer life…thanks Cocos2d-X :wink:

1. INTRODUCTION

What i want is to run the “Box2D hello world project” on my Android phone (or emulator). I managed to run the “tests examples” http://www.cocos2d-x.org/projects/cocos2d-x/wiki/How_to_run_test_cases_on_android-ndk (with a lot of difficulties! please update this article declared as “deprecated”) but impossible to find a solution to run the very simple “Box2D hello world project”.

I started by creating the “Box2D hello world project” in XCode thanks to the Box2D cocos2D-X template. I just did “New project” => “Cocos2d-X Box2D project” => “create” and ok no problem I can run it on my iPhone from Xcode.

Then, I created an empty Android project thanks to “create-android-project.sh” and transfered all the required files and directories to my project created with XCode. The method I followed is very close to what is described in this article http://gameit.ro/2012/01/creating-an-iphone-and-android-cocos2d-x-hybrid-project-updated/#comment-649 Neverthless, I did a little bit differently for the android.mk files, etc… to be closer to the “test cases” examples which work on my phone.

2. MY PROBLEM

Here is my problem:

  • my cocos2D/Box2D project perfectly compiles when running ./build_native.sh…
  • and loads the Box2D, cocos2D, cocosdenshion libraries…
  • …but doesn’t load the “game_logic” and “helloworldgame” libraries.

I can’t figure out what is wrong in my Android.mk, Application.mk files (or another problem elsewhere?).

So here are the details about my project:

I use NDK r7 and cocos2d-1.0.1-x-0.11.0. I run Mac OSX Lion.

**Structure of my folders: *
<pre>

  • cocos2d-1.0.1-x-0.11.0
    *+ Box2D
    *+ cocos2dx
    *+ CocosDenshion
    *+ agjs
    **+ agjs
    ***+ android
    ****+ assets
    ****+ bin
    ****+ gen
    ****+ jni
    *****+ helloworld
    ****+ libs
    ****+ obj
    ****+ res
    ****+ src
    **** classes
    ***+ ios
    ***+ libs )
    ++ Resources
    </pre>

**Here are the contents of my files:*

Android.mk in /agjs/agjs:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE :=* game_logic*

LOCAL_SRC_FILES := \
classes/AppDelegate.cpp \
classes/HelloWorldScene.cpp \

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../cocos2dx \
                   $(LOCAL_PATH)/../../cocos2dx/include \
                   $(LOCAL_PATH)/../../cocos2dx/platform \
                   $(LOCAL_PATH)/../../cocos2dx/platform/third_party/android/ \
                   $(LOCAL_PATH)/../../CocosDenshion/include \
                   $(LOCAL_PATH)/../.. \
                   $(LOCAL_PATH)/.. 

LOCAL_LDLIBS := -L$(call host-path, $(LOCAL_PATH)/android/libs/$(TARGET_ARCH_ABI)) \
                -lGLESv1_CM \
                -lcocos2d -llog -lcocosdenshion \
                -lbox2d  \
                -L$(call host-path, $(LOCAL_PATH)/../../cocos2dx/platform/third_party/android/libraries/$(TARGET_ARCH_ABI)) -lcurl

include $(BUILD_SHARED_LIBRARY)

Android.mk in /jni:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

subdirs := $(addprefix $(LOCAL_PATH)/../../../../,$(addsuffix /Android.mk, \
        Box2D \
          cocos2dx \
          CocosDenshion/android \
          ))

subdirs +=      $(LOCAL_PATH)/../../Android.mk \
                $(LOCAL_PATH)/helloworld/Android.mk

include $(subdirs)

Android.mk in /helloworld:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := *helloworldgame*

LOCAL_SRC_FILES := main.cpp \

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../../../../cocos2dx \
                    $(LOCAL_PATH)/../../../../../cocos2dx/platform \
                    $(LOCAL_PATH)/../../../../../cocos2dx/include \
                    $(LOCAL_PATH)/../../../.. \
                    $(LOCAL_PATH)/../../../ \
                    $(LOCAL_PATH)/../../../Classes \


LOCAL_LDLIBS := -L$(call host-path, $(LOCAL_PATH)/../../libs/$(TARGET_ARCH_ABI)) \
                -lGLESv1_CM \
                -lcocos2d -llog -lgame_logic

include $(BUILD_SHARED_LIBRARY)

Application.mk in /jni:

APP_STL := stlport_static
APP_ABI := armeabi

APP_MODULES := cocos2d cocosdenshion box2d game_logic helloworldgame

build_native.sh in /android:

NDK_ROOT=/Applications/Android/android-ndk-r7
COCOS2DX_ROOT=../../../cocos2dx
GAME_ROOT=../
GAME_ANDROID_ROOT=$GAME_ROOT/android
RESOURCE_ROOT=$GAME_ROOT/Resources
# some more code after that...

In agjs.java:

 static {

         try {
                System.loadLibrary("cocos2d"); // OK here => no exception
              } catch (UnsatisfiedLinkError use) {
                Log.e("MyApp", "WARNING: Could not load cocos2d.so");
              }

        try {
               System.loadLibrary("cocosdenshion"); // OK here => no exception
              } catch (UnsatisfiedLinkError use) {
                Log.e("MyApp", "WARNING: Could not load cocosdenshion");
            }

     try {
                System.loadLibrary("game_logic"); // NOT OK here => exception !!!
            } catch (UnsatisfiedLinkError use) {
                Log.e("MyApp", "WARNING: Could not load game_logic");
            }

                try {
                 System.loadLibrary("helloworldgame"); // NOT OK here => exception !!!
                } catch (UnsatisfiedLinkError use) {
                    Log.e("MyApp", "WARNING: Could not load game");
                }

                try {
                 System.loadLibrary("box2d"); // OK here => no exception
                } catch (UnsatisfiedLinkError use) {
                    Log.e("MyApp", "WARNING: Could not load box2d");
                }
     }

Nota: I didn’t forget to change “LOCAL_CFLAGS := ~~DUSE_FILE32API" to "LOCAL_CFLAGS :=~~DUSE_FILE32API -DGL_GLEXT_PROTOTYPES=1” in the Android.mk of cocos2d-1.0.1-x-0.11.0/cocos2dx as I use ndk r7.

Here is the error message in the console:

02-10 00:01:20.372: E/MyApp(22177): WARNING: Could not load game_logic // NOTA: due to the System.loadLibrary("game_logic") written in my code 
02-10 00:01:20.372: E/MyApp(22177): WARNING: Could not load game // NOTA: due to the System.loadLibrary("game") written in my code 
02-10 00:01:20.472: W/dalvikvm(19568): No implementation found for native Lorg/cocos2dx/lib/Cocos2dxRenderer;.nativeInit (II)V
02-10 00:01:20.472: E/AndroidRuntime(22177): FATAL EXCEPTION: GLThread 12
02-10 00:01:20.472: E/AndroidRuntime(22177): java.lang.UnsatisfiedLinkError: nativeInit
02-10 00:01:20.472: E/AndroidRuntime(22177):    at org.cocos2dx.lib.Cocos2dxRenderer.nativeInit(Native Method)
02-10 00:01:20.472: E/AndroidRuntime(22177):    at org.cocos2dx.lib.Cocos2dxRenderer.onSurfaceCreated(Cocos2dxRenderer.java:40)
02-10 00:01:20.472: E/AndroidRuntime(22177):    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1373)
02-10 00:01:20.472: E/AndroidRuntime(22177):    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1138)

Anybody can tell me how to solve my problem of library loading ?

Thanks !

I had problems with game_logic library, and didnt quite figured it out what was game_logic… so after i removed it from the loaded libraries (from both .mk file and the java System.loadLibrary(“game_logic”); call. Everything compiled right!

Im still living without game_logic.

Here is a screenshot on how my folder structure is and how my .mk files are.

I just copied Box2d cocos2dx CocosDenshion and jni folders from the cocos2dx folders and my game folder to keep everything organized. I guess i could live without the libs folder inside my game workspace, but it has only iOS code and only xcode sees it! Android used folders from the root folder. I use r7 and cocos2x version 10 (before this last one)

Hope this can help you out in any way

Thanks for your answer. I modified my project to have exactly your structure and .mk files. As there is no more “game_logic” module (and I remove the loadLibrary relative to this library in agjs.java) I have no more crash with this game_logic module (necessarily !:)) but I still get the same crash on System.loadLibrary(“helloworldgame”) (nota: “helloworldgame” equivalent to “game” in your project, I didn’t forget to change what is necessary). The error message in the console is the same as with my project structure that is to say:

02-09 23:55:57.417: E/MyApp(21938): WARNING: Could not load game //NOTA: this is the Log.e("MyApp", "WARNING: Could not load game") exception written in my code if "helloworldgame" doesn't load
02-09 23:55:57.517: W/dalvikvm(19568): No implementation found for native Lorg/cocos2dx/lib/Cocos2dxRenderer;.nativeInit (II)V
02-09 23:55:57.517: E/AndroidRuntime(21938): FATAL EXCEPTION: GLThread 12
02-09 23:55:57.517: E/AndroidRuntime(21938): java.lang.UnsatisfiedLinkError: nativeInit
02-09 23:55:57.517: E/AndroidRuntime(21938):    at org.cocos2dx.lib.Cocos2dxRenderer.nativeInit(Native Method)
02-09 23:55:57.517: E/AndroidRuntime(21938):    at org.cocos2dx.lib.Cocos2dxRenderer.onSurfaceCreated(Cocos2dxRenderer.java:40)
02-09 23:55:57.517: E/AndroidRuntime(21938):    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1373)
02-09 23:55:57.517: E/AndroidRuntime(21938):    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1138)

Nothing special in my main.cpp, just the standard Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit :

void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInit(JNIEnv*  env, jobject thiz, jint w, jint h)
{
    if (!cocos2d::CCDirector::sharedDirector()->getOpenGLView())
    {
    cocos2d::CCEGLView *view = &cocos2d::CCEGLView::sharedOpenGLView();
        view->setFrameWidthAndHeight(w, h);
        // if you want to run in WVGA with HVGA resource, set it
        // view->create(480, 320);
        cocos2d::CCDirector::sharedDirector()->setOpenGLView(view);

        AppDelegate *pAppDelegate = new AppDelegate();
        cocos2d::CCApplication::sharedApplication().run();
    }
    else
    {
        cocos2d::CCTextureCache::reloadAllTextures();
        cocos2d::CCDirector::sharedDirector()->setGLDefaultValues();
    }
}

For my information, what do you mean by “I just copied…jni folders from the cocos2dx folders and my game folder” ? I don’t understand what it means.

Thanks for your help.

Those folders i mentioned where folders from the cocos2dx root folder (usually they recomended that you build your project folder on the cocos2dx root folder, so it can find the files needed, i just tracked what folders where needed and removed the rest like tests, other libraries, etc…)

Well, seems like everything is right now, at least on the c++ build part, now your problem seems on the execution. What NDK are you building against ?

I use NDK7.

What do you mean by “build your project folder on the cocos2dx root folder”? Does it simply mean that the folder structure has to be as can be seen on your screenshot that is to say with your game folder (BrasilQuest) at the same level as the Box2D, Cocos2D, etc… folders?

I am still not sure to understand from where you copied the “jni” folder located at your “root” folder. Did you copy it from BrasilQuest/Android/jni or from /cocos2dx/platform/android/jni ? In both cases, what is the logic behind ? What is the link with the instructions given in the .mk files ?

I am also wondering: does the content of the .bash_profile file is important in our case? Indeed, all the paths you mention in your .mk files are relative (it was also the case for my files). From my point of view, the .bash_profile file is not used in such cases. Correct ? (anyway, I think that my .bash/profile file is correct…

For information, I forgot to tell that I have also this error before the erros I mentioned in my previous posts (I updated them):

02-10 15:36:58.450: W/dalvikvm(17751): No implementation found for native Lorg/cocos2dx/lib/Cocos2dxRenderer;.nativeInit (II)V

And when I try to run on emulator, I have got the following warning:

Warning once: This application, or a library it uses, is using NSQuickDrawView, which has been deprecated. Apps should cease use of QuickDraw and move to Quartz.

Thanks again for your help… Hope that I will find a solution…

Hi, Régis AND
I have the same problem with you, do you complete it??