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

Hi, i am trying to reduce the final apk size of my cocos2dx project. I have already done basic things to reduce the build size i can but still not satisfied with the result.
Things already tried:

  1. Reduced the size of the resources being used using texture packer.
  2. Removed the unused Physics engine and other unused file formats from CCConfig.h

Is there any other way, via which i can reduce my apk size ?

  1. Atlast image (Using texture packer you did)
  2. Commenting physics engine, particles, 3D libraries(I think not of any use as during release build, they’re automatically removed. @slackmoehrle Can you please confirm? )

This one is Android specific: (I don’t know what do we do for iOS)
3. Try, building only for 1 arch at a time… eg- armeabi-v7a only and not armeabi or x86 mixed.
It nearly doubles(if used 2) and triples(if used all 3 arch) the size of the final build(debug build atleast).

I am not sure if you should build for mips arch. I think that’s already commented in your code.

Check on play store, if you can put app based on architecture of device downloading it.

4. In my currently being developed game, I’m having 3 assets folder. Where I am planning to deploy, HD graphics version app separately. Note “planning”. I’ll check the final build size though once the game is completed. If it won’t be more than 5MB extra, I think I would be fine to include all 3 in one.

5. For every resolution, I’m using higher end graphics for crisper look. For example,
for res. 480-960px(consider only width wise as an example), I am using graphic of 960px, for res. 960-1280px, I am using 1280px. All games doesn’t need to have crisp looking graphics. Then pack, <960px for 480-960px, and so on…

6. Use code to draw rectangles wherever possible instead of using sprites. Using 9scale sprite helped me a lot as my game have a lot of similar looking sprites.

I’ve not published any app. May be more experienced guy can help.

I requested this topic earlier(reducing release build size), if could be listed in Programmer’s guide. May be whatever people will list here, good things can be shifted to PG by @slackmoehrle :slight_smile:

Read the last 2 sections.
http://www.cocos2d-x.org/docs/programmers-guide/advanced_topics/index.html

Hey @slackmoehrle
Can you please, tell how to ensure which is mentioned in Golden Rules section
We should use batch draw as much as possible. Cocos2d-x 3.x has auto batch support, but it needs some effort to make it work.

The link give in PG has


Which talks about polygon trimming.
This thing can be easily achieve using SpritePolygon. And it will automatically give you polygon shape of sprite instead of rectangular once. [May be you don’t wish to purchase Texture packer.]

Over optimisation is not good. For example, my game has over 85% of rectangular kind of sprites. So, for me using this would be unnecessary.

1 Like

I do believe you are correct. I will ask, just to be sure.

Well it worked in my case… 0.3 MB size was reduced after commenting those libraries in CCConfig.h.

Hi thanks :smile:
i am already building only for 1 arch at a time.
i am using low quality assets where ever possible…

i am just trying to figure out a way where we can reduce the size during compilation and linking?
is there any other way where i can reduce the size of the cocos .so and library file so that build size could be reduced ?

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.