http://box2d.org/ is a wonderful, FREE!, physics library. Without it, we probably wouldn’t have the likes of Angry Birds (since Angry Birds was built on-top of it).
But … it’s a C++ library, and the official version doesn’t play nice with iOS (iPhone/iPad). You can include the full source into your project, but then you (might) run into Apple’s bugs where C++ sometimes fails to compile correctly in Xcode. And … you get several Warnings for the box2D source, where it doesn’t quite meet Xcode’s expectations. Most teams work on a “zero warnings allowed” basis, forcing you to branch the project
.
Solution: convert box2D into a static library!
Please note: This tutorial is the MINIMUM steps we found that workaround the Xcode bugs. They SHOULD work for all other C++ libraries too – this is a more careful, cautious approach than the “standard” way you create static libraries.
But … if you see an unecessary step, or mistake, please add a comment to this post and I’ll look into it.
1. Create a new Xcode Project
When we’re done, you’ll have two items (a file and a folder) which you can drag/drop into any xcode project, and they will Just Work ™ – every time, with no code changes needed.
To start with, create a new Xcode project, and choose a type of: “Cocoa Touch Static Library”

2. Add the Box2D source
This is where it gets slightly tricky: we are going to workaround a major bug in Xcode, and a minor nuisance in the way box2D’s source code is written.
NB: box2d’s source is correct – it’s following the standards – it’s Apple that is wrong here. But … many library authors have given up, and just follow Apple’s “customized” version of the standards, because it makes life easier.
i. Download the source
First, download the box2d source code (if it’s not there, use the links from box2d.org to find it)
ii. Find the correct set of files
Inside the zip file, you’ll find a lot of stuff:

…you want the Box2D sub-folder from the above screenshot. Copy the whole thing somewhere on your hard disk (you don’t want to change the original).
iii. Duplicate the headers
This step is critical: most libraries don’t need this, but we have to workaround a bug in Xcode
- Create two new folders: “src” and “headers”
- Copy/paste the Box2D folder into “headers”, and move the original into “src” – yes, you really DO need two copies of the source!
- Move both folders (“src” and “headers”) into the folder where your new Xcode project lives. DO NOT ADD THEM TO YOUR PROJECT.
Finally … open the “headers” copy of Box2D in Finder … and “move to trash” every single file that is NOT a “.h” file.
NB: you *will* end up with two copies of every header file – one in the “headers” folder, and one in the “src” folder. That sounds strange, but it’s how we force Xcode to do what it’s supposed to do.
iv. Add to project
This step is critical: most libraries don’t need this, but we have to workaround a bug in Xcode
- Drag/drop the “src” folder into your project
- CRITICAL: “Create groups for any added folders” MUST be checked
- Drag/drop the second Box2D folder (the one inside “headers” into your project
- CRITICAL: “Create folder references for any added folders” MUST be checked
When you’re finished, it MUST look like this. If not – you did it wrong, and YOUR LIBRARY WILL NOT WORK

Note that the copy from “headers” has all the folders coloured blue, whereas the copy from “src” has all the folders coloured yellow. That is very important…
3. Fix the headers (part 2)
We’ve duplicated the headers, and added them to the project.
But now we have to workaround ANOTHER bug in Xcode – one that is fatal to the box2D project.
Also … by default, Xcode does NOT make headers available to other projects. This is a bad “default” behaviour of Xcode – Xcode knows we’re making a static library, so it’s pretty obvious we’d want people to use it!
First, remove Xcode’s buggy, incorrect header-export:
- Open the build-settings for your new library project
- Select the “Build Phases” tab
- Open the “Copy Headers” phase
- …and delete all the headers in there
Next, add the headers CORRECTLY, and make them PUBLIC:
- Drag/drop the blue “Box2D” folder from the Project Navigator into the Public section
- …NB: you *must* drag the blue folder
- …NB: you *must* drag it – if you use the small “+” button, that is for adding headers, XCODE WILL NOT DO WHAT YOU TOLD IT TO (bug).
When you’re done, you should have exactly this:

5. Make the library “universal”
For Xcode 4.0, Apple removed a *critical* feature – their build notes said it was too confusing for developers, so they simply removed it. I think it’s more likely they decided they didn’t have time to fix all the bugs in their implementation (there were quite a few)…
Anyway, we’re going to add the feature back in.
Using this StackOverflow question and answer, convert your library from “Simulator only” / “Device only”, into a library that works on both simulators AND on devices, all in one file.
Briefly:
- In the Build Settings page you already have open in Xcode, click “Add Build Phase -> Run Script Phase” at bottom right
- Copy/paste the script from StackOverflow into the script area.
Easy!
6. Build, and add to your game / app project
Hit Build, and you get a library.
However, there’s ANOTHER bug in Xcode: it will “hide” the library somewhere semi-random on your hard disk. The StackOverflow answer has step-by-step instructions for finding it (hint: look in the Build Results window in Xcode, and the script prints the location to screen, so you can find it, because Xcode hides it from you).
Now drag/drop the file (e.g. “libBox2dStatic.a”, if you called your box2d project “Box2DStatic”) into your main app project.
In Finder, in the same folder where you found the “.a” file, you’ll see a folder “usr” – also drag/drop this one into your project. (it contains all the header files that Box2D needs)
7. Configure your project to find the header files
By default, Xcode ignores incoming header files. This is poor interface design from Apple – most IDE’s would have asked you “are you adding these files to your project – or are they part of a library that you’re importing?” – but it means we have to manually tell Xcode that we just added library headers.
- IN YOUR MAIN GAME/APP: go to the Build Settings page
- Select the TARGET you’re building (not the PROJECT), and select “Build Settings” tab
- in the search box, type “header”
- Edit the “Header Search Paths” line, and add an entry (if its not there already): “$(SRCROOT)”
- Hit Enter/Return key (Xcode will often delete the new entry if you don’t do this!)
- Check the little tickbox to the left of the new entry – this is REQUIRED
When you’re done, double-click the “Header Search Paths” and check your entry is there (c.f. note above, about how Xcode often deletes new entries for no apparent reason). It should look like this:
(NB: the libxml2 line in the screenshot probably isn’t needed in your project – in this example, I used a project that already had some Header Search Paths)

8. Import Box2D, and start coding…
YOU MUST NOT #import BOX2D – it doesn’t support that usage. Instead, you must #include it – and you MUST use angle-brackets.
Here’s an example – note how the “#import” for Foundation is an import, but the Box2D is an include:

Finally: since box2d is written in C++, you MUST make your source file into Objective-C++. This is very easy – all you have to do is rename it from “.m” to “.mm”.
(if that doesn’t work, you can open the right-hand panel in Xcode, and in the “Identity and Type” section, set the File Type setting to “C++ Source File”)