How to speed up cocos2d-x build with prebuilt lib

The latest cocos2d-x comes with a new gen-libs command,which I think is really useful

What this command will do is to generate a prebuilt lib file for cocos2d-x and increase your productivity immensely by cut compile time into seconds instead of 10+ minutes.

To make everyone’s life easier, I created a repo with my sample projects here.

You can download it and skip the following steps if you just want to try it out.


And this is how you use it for your own project

Note

  1. the following method only works with 3.8 version and later
  2. This tutorial only covers ios and android, will update on how to use it with windows projects later

###1. Generate cocos libs
Simply run gen-libs script, and it will generate prebuilt libs under prebuilt folder

cocos gen-libs -m debug

I choose to generate debug version because release version will not output CCLOG :frowning:
it will make debugging much harder

###2. Create project
Create a new project so you can try it out.

cocos new test -l cpp

And delete cocos2d folder, because you don’t need them.

I recommend to put this project into a git repo at this point


###3. Modify Android project
There are two files you need to modify here

  1. proj.android/build-cfg.json
  2. proj.android/jni/Android.mk

Here are the samples:

###build-cfg.son
Remember to replace <COCOS2D-X_ROOT> with your cocos2d-x root folder

{
    "ndk_module_path" :[
        "<COCOS2D-X_ROOT>",
        "<COCOS2D-X_ROOT>/cocos/prebuilt-mk",
        "<COCOS2D-X_ROOT>/cocos",
        "<COCOS2D-X_ROOT>/external"
    ],
    "copy_resources": [
        {
            "from": "../Resources",
            "to": ""
        }
    ]
}

###Android.mk

Replace

$(call import-add-path,$(LOCAL_PATH)/../../cocos2d)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/external)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos)

with

$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos/prebuilt-mk)

In the end, your Android.mk should look like something like this.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos/prebuilt-mk)

LOCAL_MODULE := cocos2dcpp_shared

LOCAL_MODULE_FILENAME := libcocos2dcpp

LOCAL_SRC_FILES := hellocpp/main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/HelloWorldScene.cpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes

# _COCOS_HEADER_ANDROID_BEGIN
# _COCOS_HEADER_ANDROID_END


LOCAL_STATIC_LIBRARIES := cocos2dx_static

# _COCOS_LIB_ANDROID_BEGIN
# _COCOS_LIB_ANDROID_END

include $(BUILD_SHARED_LIBRARY)

$(call import-module,.)

# _COCOS_LIB_IMPORT_ANDROID_BEGIN
# _COCOS_LIB_IMPORT_ANDROID_END

Q&A

If you have problem building android projects, try the following

####project.properties
Make sure to reference the libcocos2dx project in project.properties
android.library.reference.1=<COCOS2D_X_ROOT>/cocos/platform/android/java


###4. Modify iOS project
You need to do the following

  1. drag&drop libcocos2d iOS.a to your project, and make sure you link with it for your iOS project

  2. Update Header Search Paths so all the header file points to the ones in your cocos2d-x root directory

And you are done, try it out and now your build time will be in seconds. Just keep in mind you’ll have to regenerate the prebuilt libs once you change any code in the engine.

I think this is the hidden gem in 3.8 version.

Feel free to ask me any questions.

20 Likes

Hey ,
this is very useful !
as the framework grow’s the compile time is really become bottleneck . and every trick to save compile time is great.
can you also please include the support for Windows and VC++ desktop also as its many developers main OS for development .
thanks!

Am I missing something?
My builds (n Mac for iPhone or Mac) take seconds anyway - except for the first time, or when I force a rebuild…

Sure on my mac 8 ram i5 its takes 2-4 min in the first time
but on my windows PC dual core with 4 giga ram it takes 25++ min each first time .
in the old versions 2+ it was less then 5 min …

@nite for me it doesn’t work :frowning:

I have compiled IOS libs… added to your empty project… configured root folder…

Trying to run… but getitng erro that can’t find cocos2.h file

Well done!

@yixiaoqingyuz is it worked for you? Can you please little assist as it not working on my side…

prebuilt/ios/libcocos2d iOS.a (2 slices)
Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_CCEAGLView", referenced from:
      objc-class-ref in AppController.o
  "cocos2d::GLViewImpl::_depthFormat", referenced from:
      -[AppController application:didFinishLaunchingWithOptions:] in AppController.o
  "cocos2d::GLViewImpl::_pixelFormat", referenced from:
      -[AppController application:didFinishLaunchingWithOptions:] in AppController.o
  "cocos2d::GLViewImpl::convertAttrs()", referenced from:
      -[AppController application:didFinishLaunchingWithOptions:] in AppController.o
  "cocos2d::GLViewImpl::createWithEAGLView(void*)", referenced from:
      -[AppController application:didFinishLaunchingWithOptions:] in AppController.o
  "cocos2d::GLViewImpl::create(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)", referenced from:

Wooh recompiled for 5th time gen-libs and it worked ;)))

One point still is not clear, should I use for generating libs Downloaded from github cocos2d-x version? Or I can use specifically for project(cocos new -l cpp…) generated cocos2d folder to generate prebuild libs?

How to include sdkbox to prebuilt library?

Hi @energyy

For which platform have you compiled it for ?

Hello @nite :smile:

Anything that would make the development faster, surely grabs everyone’s attention.
It’s great that v3.8 is coming with such a thing, but I have couple of questions for you -

  • How reliable is this effort, because as the project grows we may need to add some other sdk’s. Will this effect to rebuild the library in any manner ?
  • Assuming that we are sort of using a pre-compiled library, when we are cleaning and running a project, will it create any issue with that ?
  • Is SDKBOX, gonna be a inbuilt part of cocos ? Because as of now what I have came across is using sdkbox import iap not add some changes in the cocos2d folder in the project. Rectify me if I am incorrect.

Sorry for my noob questions, but I am usually like this. Ha ha :smile:

Although it a great jump from time perspective, I am worried about the flexibility
so, that we wont have to create library again and again.

Appreciate your efforts.
Good Job :smile:

@pabitrapadhy

I’m compiling it right now it for IOS, which is easier to test. So it seems that -m debug compiled files didn’t worked for my mentioned in first post project. Without this flag I was able to run it.

Yeah it’s big question how to deal with third party SDK’s integrations/recompile. Regarding SDKBOX for Android it adding few libraries and modifying Cocos2dxactivity in cocos2d-x folder.

To get it to work propertly, I had to replace the last line in project.properties in the proj.android folder with this:

android.library.reference.1=…/…/…/…/…/…/…/…/…/…/Users/Max/Library/Cocos/CocosStore/cocos2d-x-3.8/cocos/platform/android/java

The whole …/…/ is because this path gets appened to the current path, which can’t be avoided.

I also had to add /android/java because there’s the file it’s looking for.

Can this result in any bad problems?

Thanks for the guide!

Building works, but when I try to run it, my game crashes as soon as it starts up:

09-07 11:26:20.812: D/JniHelper(2318): JniHelper::setJavaVM(0xb489d200), pthread_self() = -1225323540
09-07 11:26:20.812: D/main(2318): cocos_android_app_init
09-07 11:26:20.847: D/Cocos2dxActivity(2318): model=Nexus 7
09-07 11:26:20.847: D/Cocos2dxActivity(2318): product=razor
09-07 11:26:20.847: D/Cocos2dxActivity(2318): isEmulator=false
09-07 11:26:20.861: D/Cocos2dxActivity(2318): onResume()
09-07 11:26:20.870: D/OpenGLRenderer(2318): Use EGL_SWAP_BEHAVIOR_PRESERVED: true
09-07 11:26:20.876: D/Atlas(2318): Validating map...
09-07 11:26:20.900: I/Adreno-EGL(2318): <qeglDrvAPI_eglInitialize:379>: QUALCOMM Build: 01/15/15, ab0075f, Id3510ff6dc
09-07 11:26:20.901: I/OpenGLRenderer(2318): Initialized EGL, version 1.4
09-07 11:26:20.920: D/OpenGLRenderer(2318): Enabling debug mode 0
09-07 11:26:21.114: D/cocos2d-x debug info(2318): {
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.supports_vertex_array_object: true
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.supports_BGRA8888: false
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.supports_ATITC: true
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.supports_S3TC: false
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     cocos2d.x.version: cocos2d-x-3.8
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.supports_discard_framebuffer: true
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     cocos2d.x.compiled_with_profiler: false
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.supports_PVRTC: false
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     cocos2d.x.build_type: DEBUG
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.renderer: Adreno (TM) 320
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.supports_ETC1: true
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     cocos2d.x.compiled_with_gl_state_cache: true
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.version: OpenGL ES 3.0 V@104.0 AU@  (GIT@Id3510ff6dc)
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.supports_NPOT: true
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.max_texture_units: 32
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.vendor: Qualcomm
09-07 11:26:21.114: D/cocos2d-x debug info(2318):     gl.max_texture_size: 4096
09-07 11:26:21.114: D/cocos2d-x debug info(2318): }
09-07 11:26:21.697: D/Cocos2dxActivity(2318): onWindowFocusChanged() hasFocus=true
09-07 11:26:21.898: D/cocos2d-x debug info(2318): create rendererRecreatedListener for GLProgramState
09-07 11:26:21.899: I/native-activity(2318): FrameTimer=> Initialized using timeGetTime() timer.
09-07 11:26:21.902: D/CocosPlayClient.cpp(2318): isEnabled = 0
09-07 11:26:21.902: D/CocosPlayClient.cpp(2318): isDemo = 0
09-07 11:26:21.902: D/CocosPlayClient.cpp(2318): isNotifyFileLoadedEnabled = 0
09-07 11:26:21.902: I/native-activity(2318): AppDelegat=>applicationScreenSizeChanged (1920x1104)
09-07 11:26:21.902: I/native-activity(2318): GameLayer => onScreenSizeChanged (1920x1104)
09-07 11:26:21.902: A/libc(2318): Fatal signal 11 (SIGSEGV), code 2, fault addr 0xa2a74dc0 in tid 2346 (GLThread 6994)

If I comment the prebuilt line, and build the game with a full compile, it runs fine.

Any clue what could be going wrong?

This is what the same logging looks like when I don’t use the prebuilt cocos libs:

09-07 13:03:42.310: D/JniHelper(6361): JniHelper::setJavaVM(0xb489d200), pthread_self() = -1225323540
09-07 13:03:42.310: D/main(6361): cocos_android_app_init
09-07 13:03:42.357: D/Cocos2dxActivity(6361): model=Nexus 7
09-07 13:03:42.357: D/Cocos2dxActivity(6361): product=razor
09-07 13:03:42.357: D/Cocos2dxActivity(6361): isEmulator=false
09-07 13:03:42.368: D/Cocos2dxActivity(6361): onResume()
09-07 13:03:42.383: D/OpenGLRenderer(6361): Use EGL_SWAP_BEHAVIOR_PRESERVED: true
09-07 13:03:42.391: D/Atlas(6361): Validating map...
09-07 13:03:42.421: I/Adreno-EGL(6361): <qeglDrvAPI_eglInitialize:379>: QUALCOMM Build: 01/15/15, ab0075f, Id3510ff6dc
09-07 13:03:42.426: I/OpenGLRenderer(6361): Initialized EGL, version 1.4
09-07 13:03:42.451: D/OpenGLRenderer(6361): Enabling debug mode 0
09-07 13:03:42.921: D/Cocos2dxActivity(6361): onWindowFocusChanged() hasFocus=true
09-07 13:03:43.388: I/native-activity(6361): FrameTimer=> Initialized using timeGetTime() timer.
09-07 13:03:43.390: I/native-activity(6361): AppDelegat=>applicationScreenSizeChanged (1920x1104)
09-07 13:03:43.390: I/native-activity(6361): GameLayer => onScreenSizeChanged (1920x1104)

Both should be release builds, so not sure where the extra debug logging comes from…

From extra logging I’ve gathered that the prebuilt version crashes as soon as I try to access info from the GLView (after it’s been created). In my case, it’s:

cocos2d::Director*    pDirector    = cocos2d::Director::getInstance();
if (!pDirector)    { theLog.WriteLine( "GameLayer => Aborting, no Director found!" );  return; }
// Get the GLView
cocos2d::GLView*    pGLView        = pDirector->getOpenGLView();
if (!pGLView)    { theLog.WriteLine( "GameLayer => Aborting, no GLView found!" );    return; }

theLog.WriteLine( "GameLayer => onScreenSizeChanged frameSize (%dx%d)", (int)pGLView->getFrameSize().width, (int)pGLView->getFrameSize().height );

pGLView->getFrameSize() on this last line crashes the game, meaning both director and the GLView are not null…

Here is another weird issue:
My libgame.so build without the prebuilt cocos is not even 3 MB (2,94 MB), where as the libgame.so build against the prebuilt cocos lib is 11.7 MB.

Shouldn’t the resulting libgame.so files be approximately the same size?

Btw have you successfully launched IOS version?
After running:

cocos gen-libs -m debug -p ios

Added compiled library to project, replaced path to cocos2d files…

I’m still fighting with it:

d: warning: ignoring file /Developer/projects/cocos2d-x-3.8/prebuilt/ios/libsimulatoriOS.a, missing required architecture x86_64 in file /Developer/projects/cocos2d-x-3.8/prebuilt/ios/libsimulatoriOS.a (2 slices)ld: warning: 
ignoring file /Developer/projects/cocos2d-x-3.8/prebuilt/ios/libcocos2diOS.a, missing required architecture x86_64 in file /Developer/projects/cocos2d-x-3.8/prebuilt/ios/libcocos2diOS.a (2 slices)
Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_CCEAGLView", referenced from:
      objc-class-ref in AppController.o
  "cocos2d::GLViewImpl::_depthFormat", referenced from:
      -[AppController application:didFinishLaunchingWithOptions:] in AppController.o
  "cocos2d::GLViewImpl::_pixelFormat", referenced from:
      -[AppController application:didFinishLaunchingWithOptions:] in AppController.o
  "cocos2d::GLViewImpl::convertAttrs()", referenced from:

UPD:
Ok that strange for SImulatore recompiled project without -m debug and project worked…

cocos gen-libs -p ios

Can someone explain what this debug/release for then?

Nope, haven’t started on the iOS prebuil,ts yet, still working on the Android ones.

I’m 90% sure that my issues are due to differences in compile flags between the prebuilt libs and my game.
If I do a full build on my game once (which creates all the necessary .a files), and then copy those .a files over the once generated by cocos genlibs, my game works.

Yet I still end up with a .so file that is 10Mb vs a .so file of 2.7Mb for a full compile.

I think this is due to settings in the make files in the prebuilt-mk folders, but I haven’t figured out yet how to fix this.

Bottom line, if you optimized your android build to exclude a ton of stuff that you don’t need, then do a full build of your game for a release (just # comment out the line with the prebuilt on it in your make file).
This can safe up quite a bit of Mb in your APK package…

@MFHSchoonbrood

Make file you mean Android.mk ?

Like exclude this part:

$(call import-add-path,$(LOCAL_PATH)/…/…/cocos2d/cocos/prebuilt-mk) ?

Yes and no :slight_smile:

Yes, as I think the big size issues comes from the android.mk files in the prebuilt-mk folders (in the cocos dirs).

No, as the APP_CPPFLAGS are set in the Application.mk files of your game.

Mine is very lean, which saves so much size on the final .so file. Take a look:
APP_CPPFLAGS := -frtti -std=c++11 -fsigned-char -Wno-extern-c-compat -DCC_USE_PHYSICS=0 -DCC_USE_3D_PHYSICS=0 -DCC_ENABLE_BULLET_INTEGRATION=0 -DCC_ENABLE_BOX2D_INTEGRATION=0 -DCC_ENABLE_CHIPMUNK_INTEGRATION=0 -DCC_USE_NAVMESH=0 -DCC_USE_TIFF=0 -DCC_USE_WEBP=0 -DCC_ENABLE_SCRIPT_BINDING=0

Woooh lets try your Application.mk :smiley:

All the time was wondering how to disable box2d, chipmunk and other not used stuff:)