Box2D – porting to Android NDK


Box2D is a wonderful physics engine for game developers(but not only). Its usability is proven by the fact that Angry Birds is basing on it( How to leverage from this easy-to-use and very robust engine in Android? There are already some java libraries for android which port Box2D like androidbox2d or jbox2d. But I think(maybe I’m wrong) that most of game developers want to write a Android Game in c/c++ using NDK. This article is about how to do it. A few weeks ago I decided to write a game(AirHockey) and to use Box2D(for learning reasons) and spent a some time to properly compile it to make it available from JNI code. It was hard to find any info about it in google, one book describe it but after following it step-by-step It didn’t work. After some research and attempts I finally forced it to work and decided to share complete solution with others.


First you need to download Box2D from here: I have version 2.1.2 and don’t know if further steps is right for newer version(should be). Then unpack .zip file. You should get Box2D_vX.Y.Z folder. Inside this directory you have 2 dirs – Box2D and Contributions. Please copy the first folder(Box2D) to android-ndk-rX/sources. Now you should have a folder android-ndk-rX/sources/Box2D. Go inside it. You should see next bunch of directories: Box2D, Build, Building.txt, CMakeLists.txt, Documentation, freeglut, glui, HelloWorld, License.txt, Readme.txt, Testbed.
Now you need to add file under above dir(Android-ndk-rX/sources/Box2D) with exactly this content:

LOCAL_PATH:= $(call my-dir)

LS_CPP:= $(subst $(1)/,,$(wildcard $(1)/$(2)/*.cpp))
BOX2D_CPP:= $(call LS_CPP, $(LOCAL_PATH), Box2D/Collision) \
            $(call LS_CPP, $(LOCAL_PATH), Box2D/Collision/Shapes) \
            $(call LS_CPP, $(LOCAL_PATH), Box2D/Common) \
            $(call LS_CPP, $(LOCAL_PATH), Box2D/Dynamics) \
            $(call LS_CPP, $(LOCAL_PATH), Box2D/Dynamics/Contacts) \
            $(call LS_CPP, $(LOCAL_PATH), Box2D/Dynamics/Joints) \
            $(call LS_CPP, $(LOCAL_PATH), Box2D/Rope)

include $(CLEAR_VARS)

LOCAL_MODULE:= box2d_static
Box2D/Collision/Shapes/b2CircleShape.cpp \
Box2D/Collision/Shapes/b2PolygonShape.cpp \
Box2D/Collision/b2BroadPhase.cpp \
Box2D/Collision/b2CollideCircle.cpp \
Box2D/Collision/b2CollidePolygon.cpp \
Box2D/Collision/b2Collision.cpp \
Box2D/Collision/b2Distance.cpp \
Box2D/Collision/b2DynamicTree.cpp \
Box2D/Collision/b2TimeOfImpact.cpp \
Box2D/Common/b2BlockAllocator.cpp \
Box2D/Common/b2Math.cpp \
Box2D/Common/b2Settings.cpp \
Box2D/Common/b2StackAllocator.cpp \
Box2D/Dynamics/Contacts/b2CircleContact.cpp \
Box2D/Dynamics/Contacts/b2Contact.cpp \
Box2D/Dynamics/Contacts/b2ContactSolver.cpp \
Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.cpp \
Box2D/Dynamics/Contacts/b2PolygonContact.cpp \
Box2D/Dynamics/Contacts/b2TOISolver.cpp \
Box2D/Dynamics/Joints/b2DistanceJoint.cpp \
Box2D/Dynamics/Joints/b2FrictionJoint.cpp \
Box2D/Dynamics/Joints/b2GearJoint.cpp \
Box2D/Dynamics/Joints/b2Joint.cpp \
Box2D/Dynamics/Joints/b2LineJoint.cpp \
Box2D/Dynamics/Joints/b2MouseJoint.cpp \
Box2D/Dynamics/Joints/b2PrismaticJoint.cpp \
Box2D/Dynamics/Joints/b2PulleyJoint.cpp \
Box2D/Dynamics/Joints/b2RevoluteJoint.cpp \
Box2D/Dynamics/Joints/b2WeldJoint.cpp \
Box2D/Dynamics/b2Body.cpp \
Box2D/Dynamics/b2ContactManager.cpp \
Box2D/Dynamics/b2Fixture.cpp \
Box2D/Dynamics/b2Island.cpp \
Box2D/Dynamics/b2World.cpp \


Ok, we have done everything by Box2D side. Now it will be attached to your project if you care of join this library. How?

Inside of your project(in JNI directory) you need to 2 lines:
-LOCAL_STATIC_LIBRARIES := box2d_static – before “include $(BUILD_SHARED_LIBRARY)”
-$(call import-module,box2d) – after “”include $(BUILD_SHARED_LIBRARY)”).
For instance my looks like:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := game_shared


LOCAL_SRC_FILES := main.cpp \
                   ../../Classes/AppDelegate.cpp \
                   ../../Classes/GameLayer.cpp \
                   ../../Classes/Objects/Table.cpp \
                   ../../Classes/Objects/Player.cpp \
                   ../../Classes/Objects/Puck.cpp \
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes                   

LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static cocosdenshion_static cocos_extension_static

$(call import-module,CocosDenshion/android) \
$(call import-module,cocos2dx) \
$(call import-module,extensions) \
$(call import-module,box2d)

Now you can use Box2D in your project!:) Just include it: #include <Box2D/Box2D.h> in .h or .cpp files where you want to use Box2D objects;)

Here is API docs of Box2D:

Enjoy your adventure with Box2D in Android NDK;)

This entry was posted in Android programming and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s