How to reduce the final build size of a cocos2dx project?

How much space is the executable taking up in your apk vs. the assets and other files?

Hey @slackmoehrle

You discussed abut it?

Hey @kuldeepteekas
Today, I checked my debug and release build(incomplete game)…

Resources folder size: 8.2MB(Some are unused, so clearly they’re auto removed in both builds)
Debug : 9.9MB
Release: 8.8MB

I’ve also put 3D libraries to 0. But I think(can be wrong though) they anyways getting removed automatically, but just for the sake, I’ve done.

Further optimizations, I can think are:
1) Optimize my graphics https://tinypng.com/
Don’t know, how well it would got but will try and check.

2) Separate sd and md release apk with hd release. If the difference is >5MB, I’ll probably release it separately.

I am only buliding with arch armeabi-v7a for android.
Hopefully, it will work for all android devices. As, I don’t want to include armeabi, x86, mips, mips-r2, mips-r2-sf etc. which are commented in Application.mk for usage on need.

Hey @smitpatel88 @slackmoehrle , any idea if building with only armeabi-v7a for android fine?

I need to follow-up on this.

FWIW I’ve found you need to set the COCOS_xxx preprocessor symbols for best results (smallest code size) and not just rely on dead code stripping in the build.

For my build I’m setting the following to 0:
CC_ENABLE_SCRIPT_BINDING
CC_USE_JPEG
CC_USE_TIFF
CC_USE_WEBP
CC_USE_PHYSICS
CC_USE_3D_PHYSICS
CC_ENABLE_BULLET_INTEGRATION
CC_ENABLE_CHIPMUNK_INTEGRATION
CC_USE_NAVMESH

With these settings an “empty” project that just opens a black screen has a 600k arm7+arm64 fat executable on iOS.

4 Likes

Thanks @nivrig for sharing.
I’ve now put to 0 following which I didn’t do earlier:
CC_ENABLE_SCRIPT_BINDING
CC_USE_JPEG
CC_USE_TIFF
CC_USE_WEBP
CC_USE_NAVMESH

My new debug.apk size reduced from 10MB to 9.7MB :smiley:

Can you please tell what’s this arm64? :slight_smile:
I mean, do I need to this for android devices, or just arm-v7a is enough!
I am building just for armeabi-v7a for android.

1 Like

arm64 is an architecture for iOS. I’m afraid I don’t know much about Android development so I can’t answer your questions, sorry.

Also I’ve noticed that using TTF fonts adds a lot to the code size because the freetype library is huge.

Yeah you’re correct, my fonts are alone 900Kb and may be I add more fonts later but TTF fonts are convenient for changing colors and font sizes, so I think it’s fine to add 900Kb for this.

http://www.cocos2d-x.org/docs/programmers-guide/ui_components/index.html

Is it fine if I remove the libraries which are not used by my game?
from /cocos/Android.mk

LOCAL_SRC_FILES := \
cocos2d.cpp \
2d/CCAction.cpp \
2d/CCActionCamera.cpp \
2d/CCActionCatmullRom.cpp \
2d/CCActionEase.cpp \
2d/CCActionGrid.cpp \
2d/CCActionGrid3D.cpp \
2d/CCActionInstant.cpp \
2d/CCActionInterval.cpp \
2d/CCActionManager.cpp \
2d/CCActionPageTurn3D.cpp \
2d/CCActionProgressTimer.cpp \
2d/CCActionTiledGrid.cpp \
2d/CCActionTween.cpp \
2d/CCAnimation.cpp \
2d/CCAnimationCache.cpp \
2d/CCAtlasNode.cpp \
2d/CCCamera.cpp \
2d/CCCameraBackgroundBrush.cpp \
2d/CCClippingNode.cpp \
2d/CCClippingRectangleNode.cpp \
2d/CCComponent.cpp \
2d/CCComponentContainer.cpp \
2d/CCDrawNode.cpp \
2d/CCDrawingPrimitives.cpp \
2d/CCFastTMXLayer.cpp \
2d/CCFastTMXTiledMap.cpp \
2d/CCFont.cpp \
2d/CCFontAtlas.cpp \
2d/CCFontAtlasCache.cpp \
2d/CCFontCharMap.cpp \
2d/CCFontFNT.cpp \
2d/CCFontFreeType.cpp \
2d/CCGLBufferedNode.cpp \
2d/CCGrabber.cpp \
2d/CCGrid.cpp \
2d/CCLabel.cpp \
2d/CCLabelAtlas.cpp \
2d/CCLabelBMFont.cpp \
2d/CCLabelTTF.cpp \
2d/CCLabelTextFormatter.cpp \
2d/CCLayer.cpp \
2d/CCLight.cpp \
2d/CCMenu.cpp \
2d/CCMenuItem.cpp \
2d/CCMotionStreak.cpp \
2d/CCNode.cpp \
2d/CCNodeGrid.cpp \
2d/CCParallaxNode.cpp \
2d/CCParticleBatchNode.cpp \
2d/CCParticleExamples.cpp \
2d/CCParticleSystem.cpp \
2d/CCParticleSystemQuad.cpp \
2d/CCProgressTimer.cpp \
2d/CCProtectedNode.cpp \
2d/CCRenderTexture.cpp \
2d/CCScene.cpp \
2d/CCSprite.cpp \
2d/CCSpriteBatchNode.cpp \
2d/CCSpriteFrame.cpp \
2d/CCSpriteFrameCache.cpp \
2d/CCTMXLayer.cpp \
2d/CCTMXObjectGroup.cpp \
2d/CCTMXTiledMap.cpp \
2d/CCTMXXMLParser.cpp \
2d/CCTextFieldTTF.cpp \
2d/CCTileMapAtlas.cpp \
2d/CCTransition.cpp \
2d/CCTransitionPageTurn.cpp \
2d/CCTransitionProgress.cpp \
2d/CCTweenFunction.cpp \
2d/CCAutoPolygon.cpp \
3d/CCFrustum.cpp \
3d/CCPlane.cpp \
platform/CCFileUtils.cpp \
platform/CCGLView.cpp \
platform/CCImage.cpp \
platform/CCSAXParser.cpp \
platform/CCThread.cpp \
$(MATHNEONFILE) \
math/CCAffineTransform.cpp \
math/CCGeometry.cpp \
math/CCVertex.cpp \
math/Mat4.cpp \
math/Quaternion.cpp \
math/TransformUtils.cpp \
math/Vec2.cpp \
math/Vec3.cpp \
math/Vec4.cpp \
base/CCNinePatchImageParser.cpp \
base/CCStencilStateManager.cpp \
base/CCAsyncTaskPool.cpp \
base/CCAutoreleasePool.cpp \
base/CCConfiguration.cpp \
base/CCConsole.cpp \
base/CCController-android.cpp \
base/CCController.cpp \
base/CCData.cpp \
base/CCDataVisitor.cpp \
base/CCDirector.cpp \
base/CCEvent.cpp \
base/CCEventAcceleration.cpp \
base/CCEventController.cpp \
base/CCEventCustom.cpp \
base/CCEventDispatcher.cpp \
base/CCEventFocus.cpp \
base/CCEventKeyboard.cpp \
base/CCEventListener.cpp \
base/CCEventListenerAcceleration.cpp \
base/CCEventListenerController.cpp \
base/CCEventListenerCustom.cpp \
base/CCEventListenerFocus.cpp \
base/CCEventListenerKeyboard.cpp \
base/CCEventListenerMouse.cpp \
base/CCEventListenerTouch.cpp \
base/CCEventMouse.cpp \
base/CCEventTouch.cpp \
base/CCIMEDispatcher.cpp \
base/CCNS.cpp \
base/CCProfiling.cpp \
base/CCProperties.cpp \
base/CCRef.cpp \
base/CCScheduler.cpp \
base/CCScriptSupport.cpp \
base/CCTouch.cpp \
base/CCUserDefault-android.cpp \
base/CCUserDefault.cpp \
base/CCValue.cpp \
base/ObjectFactory.cpp \
base/TGAlib.cpp \
base/ZipUtils.cpp \
base/allocator/CCAllocatorDiagnostics.cpp \
base/allocator/CCAllocatorGlobal.cpp \
base/allocator/CCAllocatorGlobalNewDelete.cpp \
base/atitc.cpp \
base/base64.cpp \
base/ccCArray.cpp \
base/ccFPSImages.c \
base/ccRandom.cpp \
base/ccTypes.cpp \
base/ccUTF8.cpp \
base/ccUtils.cpp \
base/etc1.cpp \
base/pvr.cpp \
base/s3tc.cpp \
renderer/CCBatchCommand.cpp \
renderer/CCCustomCommand.cpp \
renderer/CCGLProgram.cpp \
renderer/CCGLProgramCache.cpp \
renderer/CCGLProgramState.cpp \
renderer/CCGLProgramStateCache.cpp \
renderer/CCGroupCommand.cpp \
renderer/CCMaterial.cpp \
renderer/CCMeshCommand.cpp \
renderer/CCPass.cpp \
renderer/CCPrimitive.cpp \
renderer/CCPrimitiveCommand.cpp \
renderer/CCQuadCommand.cpp \
renderer/CCRenderCommand.cpp \
renderer/CCRenderState.cpp \
renderer/CCRenderer.cpp \
renderer/CCTechnique.cpp \
renderer/CCTexture2D.cpp \
renderer/CCTextureAtlas.cpp \
renderer/CCTextureCache.cpp \
renderer/CCTextureCube.cpp \
renderer/CCTrianglesCommand.cpp \
renderer/CCVertexAttribBinding.cpp \
renderer/CCVertexIndexBuffer.cpp \
renderer/CCVertexIndexData.cpp \
renderer/ccGLStateCache.cpp \
renderer/CCFrameBuffer.cpp \
renderer/ccShaders.cpp \
deprecated/CCArray.cpp \
deprecated/CCDeprecated.cpp \
deprecated/CCDictionary.cpp \
deprecated/CCNotificationCenter.cpp \
deprecated/CCSet.cpp \
deprecated/CCString.cpp \
physics/CCPhysicsBody.cpp \
physics/CCPhysicsContact.cpp \
physics/CCPhysicsJoint.cpp \
physics/CCPhysicsShape.cpp \
physics/CCPhysicsWorld.cpp \
physics3d/CCPhysics3D.cpp \
physics3d/CCPhysics3DWorld.cpp \
physics3d/CCPhysics3DComponent.cpp \
physics3d/CCPhysics3DDebugDrawer.cpp \
physics3d/CCPhysics3DObject.cpp \
physics3d/CCPhysics3DShape.cpp \
physics3d/CCPhysicsSprite3D.cpp \
physics3d/CCPhysics3DConstraint.cpp \
navmesh/CCNavMesh.cpp \
navmesh/CCNavMeshAgent.cpp \
navmesh/CCNavMeshDebugDraw.cpp \
navmesh/CCNavMeshObstacle.cpp \
navmesh/CCNavMeshUtils.cpp \
../external/ConvertUTF/ConvertUTFWrapper.cpp \
../external/ConvertUTF/ConvertUTF.c \
../external/tinyxml2/tinyxml2.cpp \
../external/unzip/ioapi_mem.cpp \
../external/unzip/ioapi.cpp \
../external/unzip/unzip.cpp \
../external/edtaa3func/edtaa3func.cpp \
../external/xxhash/xxhash.c \
../external/poly2tri/common/shapes.cc \
../external/poly2tri/sweep/advancing_front.cc \
../external/poly2tri/sweep/cdt.cc \
../external/poly2tri/sweep/sweep_context.cc \
../external/poly2tri/sweep/sweep.cc \
../external/clipper/clipper.cpp

Straightforward things like Camera, Grid, Grid3D, etc can be removed I guess!

Did you try anything else apart from removing CCConfig.h ?
I think removing .h files from also can work cocos2d.h

And also from where is this UISlider coming?

Looks like, modifying would help.

**1)** uiCMakeLists.txt
**2)** 2d/CMakeLists.txt
**3)** 3d/CMakeLists.txt
**3)** physics3d/CMakeLists.txt
**4)** physics/CMakeLists.txt
**5)** network/CMakeLists.txt
**6)** navmesh/CMakeLists.txt

@slackmoehrle Can you please confirm from developer team if we can safely remove it.
I want to remove certain libraries from it for example I am not using 3,4,5,6 entirely and few things in 1 and 2.

While building, I can clearly see that those things are being compiled which are not at at all used in my project.
@ricardo Can you also share your advice ?

Waiting for other people’s opinion/experience.

[EDIT]: I tried editing in lot of files but no success. Only thing that has reduced size till now is How to reduce the final build size of a cocos2dx project? - #11 by catch_up

Thanks :slight_smile:

@catch_up codes that are not used will be removed in linking stage, but you can not remove .cpp files by yourself, it requires you being familiar with the codes. As you said, you don’t use Camera, indeed, there is a default camera, so you can not remove it.

Building only armeabi-v7a is ok since there are few armeabi devices. cocos2d-x use armeabi by default just because cocos2d-x wants to support as many devices as possible.

1 Like

Hey @zhangxm. Thanks for reply.

Please see here. I am able to reduce size by making them as 0 since I am not usng them.
Which means, unused code is not getting removed at the time of linking for sure, atleast not all if some.

So, I wanted to know what else I can remove from the code to REDUCE the build size.
ALSO, what part of code to remove to IMOROVE build time.

I agree that I shouldn’t remove randomly. But since the code is decoupled, there should be some file/functionality which helps to disable/remove the unneeded modules easily.

For example- I don’t use 3D but still it gets build and some similarly some other modules are there which I don’t use but are used up in build time… which is not good…

Be curious if you improve things further. You’ll probably have to create some define(s) and wrap all associated code. What other things are you not using?

3D? Mesh?
Actions?

While it’d be great if the engine was more modular in its build workflow I think pre-built libraries would be the most efficient use of your time …??

These macros are different, they are needed by engine if the macros take effect. But some modules are not needed , such as spine, cocosbuilder and so on. That’s why these macros exist.

1 Like

[quote=“nivrig, post:10, topic:32875”]
For my build I’m setting the following to 0:

CC_ENABLE_SCRIPT_BINDING   0
CC_USE_JPEG   0
CC_USE_TIFF   0
CC_USE_PHYSICS  0
CC_USE_3D_PHYSICS  0
CC_ENABLE_BULLET_INTEGRATION  0
CC_ENABLE_CHIPMUNK_INTEGRATION  0
CC_USE_NAVMESH 0

I’ve set all this to 0 and for iOS&Mac I’ve got build succeeded.
However for android I’m building cocos2d-x pre-build libs using:
cocos gen-libs -p android --ap android-19 --app-abi x86:armeabi-v7a

and got errors:

[x86] Compile++      : cocos2d_lua_static <= CCLuaEngine.cpp
In file included from /Volumes/MacData/Cocos2d-x/cocos/3d/../scripting/lua-bindings/manual/CCLuaBridge.h:30:0,
                 from /Volumes/MacData/Cocos2d-x/cocos/scripting/lua-bindings/proj.android/../manual/CCLuaBridge.cpp:25:
/Volumes/MacData/Cocos2d-x/cocos/3d/../scripting/lua-bindings/manual/CCLuaEngine.h:55:1: error: expected class-name before '{' token
 {
 ^
/Volumes/MacData/Cocos2d-x/cocos/3d/../scripting/lua-bindings/manual/CCLuaEngine.h:80:13: error: 'ccScriptType' does not name a type
     virtual ccScriptType getScriptType() override {

With enabling CC_ENABLE_SCRIPT_BINDING 1 next time I’ve got errors with physics:

[x86] Compile++      : cocos2d_lua_static <= lua_cocos2dx_experimental_manual.cpp
/Volumes/MacData/Cocos2d-x/cocos/scripting/lua-bindings/proj.android/../auto/lua_cocos2dx_auto.cpp: In function 'int lua_cocos2dx_Node_setPhysicsBody(lua_State*)':
/Volumes/MacData/Cocos2d-x/cocos/scripting/lua-bindings/proj.android/../auto/lua_cocos2dx_auto.cpp:4349:15: error: 'class cocos2d::Node' has no member named 'setPhysicsBody'
         cobj->setPhysicsBody(arg0);
               ^

Again, all works for iOS&Mac with all disabled but for android disabling CC_ENABLE_SCRIPT_BINDING and CC_USE_PHYSICS cause errors.
@zhangxm I think this is an issue. Can you try to build this way and fix as I believe this is a bug.

You should re-generate binding codes since you changed the macro.

here is a lite version of cocos2d-x

What do you mean? I don’t understand, I’m just executing cocos gen-libs…

Why WebP removed in it? I’m using WebP as one type resource for both platforms. Thats what I need most.
And moreover I’m using SpriteBuilderX with custom cocos, based on current official version.

You modified the macro value from 1 to 0, you should re-generate binding codes to unbind some functions. You need to set up environments as the readme says, then you can do

cd cocos2dx_root/tools/tolua
python ./genbindings.py

cd ../tojs
python ./genbindings.py
1 Like

Ok, I probably should try it. But how do you think it will save my final build size? I’d prefer never use any bindings… or scripts and save build time and size.