While Cocos2D is compatible with ARC, simply enabling ARC in the project’s Build Setting will throw several hundreds of errors in your face. Cocos2D doesn’t provide ARC-enabled project templates. Thus this tutorial about how to enable ARC in a newly created Cocos2D Xcode Project.

While none of these steps are overly difficult, you’ll notice there’s plenty of steps to perform. Unavoidably, and on the off chance you don’t already know, I’d like to recommend Kobold2D to you if you want to write ARC enabled Cocos2D apps. Because none of the steps below, really zero, zilch, nada, niente, keine are necessary to enable ARC in Kobold2D. That’s because it ships with 15 template projects all of which have ARC enabled out of the box. And Kobold2D 2.0 with cocos2d-iphone 2.0 is just around the corner.

Self-advertisment aside, these steps are tested with cocos2d-iphone v2.0 but should also work with cocos2d-iphone v1.1 – but admittedly I haven’t tested the process with the v1.1 version. If you find anything that’s not quite working with v1.1 please leave a comment. Preferably with the solution, that’ll be awesome!

UPDATE: I released a video version of this tutorial:

Install Xcode, Cocos2D, and the Cocos2D Xcode Templates

Let’s first check that you have all the prerequisites. With iOS devices selling like Playboys in the 70s these days, there’s got to be those who haven’t gotten to install Xcode or download Cocos2D yet. And for everyone else this is a version-check and a reminder to upgrade their tools and cocos2d frequently. The latter being particularly simple if you’d been using Kobold2D. Just saying.

  1. Download and Install Xcode 4. Now might be a good time to upgrade if you’re not on Xcode 4.2 – because there’s no ARC for you without at least Xcode 4.2.
  2. Download Cocos2D and extract the cocos2d-iphone-****.tar file by double-clicking it. The filename varies depending on the cocos2d version.
  3. Open Terminal.app and enter:
    ./path-to-cocos2d-iphone/install-templates.sh -f

    Note: The path-to-cocos2d-iphone needs to be replaced with the actual path to the cocos2d directory. For example, if you are using Safari and extracted the file cocos2d-iphone-2.0-rc0a.tar where Safari downloaded it, then this command should work for you: ./Downloads/cocos2d-iphone-2.0-rc0a/install-templates.sh -f.
    Note that the leading dot is essential, without it you’ll most likely get a “No such file or directory” error.

    The install-templates.sh script will install the cocos2d-iphone Xcode templates. You have to run this script each time you download a new Cocos2D version to make sure that newly created cocos2d projects use the latest cocos2d version.

    The template files are copied to the user’s Developer directory which is ~/Library/Developer/Xcode/Templates. This is the directory you want to browse to in Finder if you ever wanted to delete the cocos2d Xcode templates. Perhaps to remove older version files or in case the install script fails with a permission issue.

    The -f switch forces the script to replace any existing cocos2d template files, so that you don’t get any errors should you have previously installed the cocos2d Xcode templates.

ARC-ifying the Cocos2D code of the Template Projects

First we are refactoring the Cocos2D code away from your project and into a static library, so that your ARC-enabled code and the non-ARC cocos2d code can work happily together. If you were to enable ARC without separating the cocos2d source code the compiler would not be very happy. The Cocos2D codebase may be compatible but it’s not compliant with ARC, meaning Cocos2D itself is not using ARC and must be compiled with ARC disabled.

The following steps are the same for all Cocos2D Xcode Project Templates. I chose the Box2D template but you can apply the same steps to any of the other templates as well.

  1. Open Xcode (duh!)
  2. Create a new project, for example by selecting from the menu: File -> New -> Project…
  3. Select the desired cocos2d Xcode Template: Box2D, Chipmunk or no physics for either iOS or Mac OS X.
  4. Click Next and give the new project an appropriate name and save it anywhere (but remember where).
  5. Build & Run the project to verify that it’s working. You never know.
  6. Delete the libs group in Xcode. Make sure to select Remove References in the confirmation dialog because you’ll still be needing the files later on, so don’t trash them.
  7. Select the Project itself in the Project Navigator. It’s the first entry with the blue document icon in the treeview pane on the left side of the Xcode window. Then click the Add Target button at the bottom, just below the Project/Targets list.
  8. In the Add Target template dialog navigate to the Framework & Library group and select Cocoa Touch Static Library respectively Cocoa Library if you develop a Mac application. Then click Next.
  9. Name the library appropriately, for example cocos2d-library. Be sure to deselect both Include Unit Tests and Use Automatic Reference Counting.

    Warning: Some recommend to use the -fno-objc-arc Compiler Flag to disable ARC on a per-source-file basis. This is only helpful if you have very few source code files which require this flag where an extra static library target would be overkill. Since you’ll have to add the flag to each cocos2d source code file individually – one-by-one – and there being anywhere between 100 and 150 source files, I strongly discourage going down this road. Plus it will be a maintenance nightmare whenever you upgrade cocos2d.

  10. Once created, the cocos2d-library target is selected and the Build Settings pane is shown. You need to navigate the Build Settings to make two changes to the Search Paths section. The easiest way to find these settings is by entering “search” to the search filter textbox in the upper right corner of the Build Settings pane.

    Set the Always Search User Paths setting to Yes and set the User Header Search Paths to the somewhat cryptic ./** string.

    Note: You can edit the User Header Search Paths setting in two ways, one by clicking it twice with a delay between the clicks – this allows you to enter the text directly. Alternatively you can double-click the field which brings up an additional dialog with a checkbox in it. In that case, either enter just a dot and click the checkbox, or enter the full string ./** but do not check the checkbox. Otherwise you might end up with the string ./**/** which will cause compiler errors. Be sure to verify the string is correct after the edit dialog closes, since Xcode might change the string depending on whether the checkbox is checked.

    Warning: The search path ./** is a quick & dirty short-hand for “search the project’s folder and all of its subfolders recursively”. This works fine as long as any header file you create or add to your project does not have the same name as a header file in the libs folder. For example, you must not add a header file named CCNode.h to your project, because the compiler will be confused which CCNode.h to use – the one from your project or the one provided by cocos2d-iphone. This applies to all files in the path, including those that aren’t referenced by the Xcode project.

  11. Select the original target of the project. That means the one that was already there, the one that’s building your app, not the cocos2d-library target you just added. Select the Build Phases tab and expand the Link Binary With Libraries list.
  12. Click on the + button at the bottom of the list, select the libcocos2d-library.a file and click the Add button. This will link the cocos2d library code to your project’s target.
  13. Now it’s time to re-add the cocos2d files. Use File -> Add Files to “name-of-project”… to bring up the file dialog. Navigate to and select the libs folder. Make sure the Destination checkbox is unchecked and the Create groups for any added folders radio button is selected. Finally verify that the cocos2d-library target is the only target whose checkbox is checked before clicking the Add button.
  14. Build and run to make sure everything works now that the cocos2d code was separated into a static library.

Enabling ARC in your project

Now that the cocos2d code is separated from your project’s code, you can use the built-in Xcode ARC conversion tool to update the project template code to use ARC. This will also enable the appropriate Build Settings.

  1. From the Xcode menu choose Edit -> Refactor -> Convert to Objective-C ARC…. This brings up a dialog where you can select the targets to convert. Select only your app’s target but not the cocos2d-library target. Then click on Check.
  2. Xcode will build your code with ARC enabled and then present you with a wizard that helps you convert the project’s code to ARC. Read the text and click Next.
  3. Xcode will show a dialog that allows you to review the changes it is about to make. You can safely accept all of these changes.
  4. Build, run and rejoice: Your project’s code is now ARC-enabled!

Cleaning up (optional)

When you created the cocos2d-library target it also added three source code files to the project that you don’t need. You can safely delete (trash) the cocos2d-library group and all the files in it.

You only need to make a small change to the Build Settings of the cocos2d-library target. Locate the Prefix Header Build Setting, select it and press the Delete key so that the Prefix Header setting is empty. Alternatively just keep the prefix header file and only delete the two other files (cocos2d-library.h and .m).

Enjoy your ARC, WOOF, WOOF, GRRRRRR!

This should make it straightforwd for everyone to enable ARC in a Cocos2D project. Of course you can always just get Kobold2D and not concern yourself with these nasty technical things at all.

I hope you enjoyed this tutorial. Please leave a comment if you found any discrepancies, specifically since newer cocos2d or Xcode versions might behave slightly different. I’d also appreciate it if you’d tweet, like or plus-one this article if you liked it. Thank you!


This article was brought to you by ...

I very much enjoy the learning process, the pushing of boundaries (mine and yours and that of technology), having the freedom to pursue whatever is on my mind, to boldly program what no one has programmed before, and to write about what I've learned. Help me help you by browsing the products in the Learn Cocos2D Store.

74 Responses to “Enable ARC in a Cocos2D Project: The Step-by-Step-How-To-Guide Woof-Woof!”

  1. Mark says:

    Steffan, Thanks for the great post.

    I have followed this approach when updating my project to use the new cocos2d-1.1-RC0 version. Everything is working fine using the simulator for both iPad and iPhone with iOS 5 and 6.

    But, I am getting errors when I try to build for an actual iOS device.
    I have a warning that says:
    cocos2d-library was rejected as an implicit dependency for ‘libcocos2d-library.a’ because its architectures ‘armv7′ didn’t contain all required architectures ‘armv7 armv7s’

    And then an Apple Mach-O Linker error saying: ld: library not found for -lcocos2d-library

    Any help with a solution to this issue would be appreciated.

    Thanks
    Mark

  2. Hector says:

    Hello, thanks for the article

    I am trying to add Cocos2D to an existing project which uses ARC (so I think the “Enabling ARC in your project” are not necessary)

    I added the cocos2d static library without using ARC but when I try to compile it I get several errors about ARC Restrictions.

    Is there a way to add a library and remove ARC compilation from it instead of converting my project target to ARC from a non-ARC template?

    • Hector says:

      Ok forget it, somehow the Cocos2D sources appeared on my project target’s “Compile Sources” group instead of in the static library.

      Now I’m surprised of the amount of deprecation warnings…

      • Sounds like you forgot to select the right target respectively uncheck your app target when adding the files.

        You mean deprecated as in things that are deprecated in the iOS SDK? Perhaps you’re using an old version of cocos2d? v2.0 or 2.1 (beta) should be ok. v1.x should no longer be used for new projects. If you upgraded cocos2d, the deprecation will be from things changed in cocos2d. Check the ccDeprecated.h/.m files for the correct way to change each deprecated method/property/class.

        • Aron says:

          Hi Steffen

          I’m getting some depreciation warnings as well, 11 in total, mostly around CCTexture2D. Cocos2d seems to be using UILineBreak etc instead of the updated NS as of iOS 6, nothing major (this is using the latest version of cocos2d and iOS sdk).

          Reading through your latest book at the moment, i’ve wanted to get into iOS game dev for ages and im finally starting to get into it now. Your writing is terrific, keep up the great work! :D

  3. Timon says:

    Thanks for your Tutorial, Steffen!

    When i try to build my project, I get the same same error as Mark did. But it doesn’t help setting “Build Active Architecture Only” to “No”.

    Thank you very much for your help.
    Timon

    • Aron says:

      Hi Timon

      I had this problem as well. Did you make sure that it’s set in the project and BOTH targets? That always trips me up.

      Good luck!

      Aron

  4. Lawrence says:

    Thanks Mark and Steffen,

    Setting the “Build Active Architecture Only” flag to No resolved my problem. Just for feedback, the cocos2d 2.0 has the deprecation warnings also. But it can run anyway, cheers!

    PS, same as Aron, I want to get into game develop for a long time. Finally, I found iOS is just for me. I am reading Steffen’s latest book now. Thanks for the great work,

    Sincerely,
    Lawrence

  5. John says:

    Steffen

    Thanks for tutorial I was able to convert app to arc but, when I add link library cocos2d-library.a file stays red on the list and when I run code it compiles then it gives a run time error. EXC_Breakpoint. I have builded project from scratch few times but I come across to same problem every time. I use Xcode 4.5 IOS 6. What do you think problem might be?

  6. John says:

    Steffen Problem was, I guess, I was creating app with Xcode 4.5 for IOS 6 , Installing previous version of Xcode and installing 5.1 simulator solved the problem. Now code both runs on Simulator for 5.1 and Simulator for IOS 6 without any errors.

    but when I deploy the code to IOS 5.1 device I get following error:

    ld: library not found for -lcocos2d-library
    clang: error: linker command failed with exit code 1

  7. John says:

    Steffen

    Mark’s solution worked for me as well.
    The “Build Active Architecture Only” flag was set to Yes for the library. Changing this to No for the library fixed the issue.

  8. [...] flags on it, meaning I didn’t have to worry too much about memory leaks. To do this, I followed this blog – but the gist of it is [...]

  9. Thomas B says:

    In following your instructions I have found a mistake.
    I am using Cocos2d 2.0, Xcode 4.5.2, Mac OS 10.8.2

    When following the steps under “ARC-ifying the Cocos2D code of the Template Projects” When you get to step 14 it will only run without crashing using iOS 6.0

    If one tries to run it under 5.0 or 5.1 it will crash
    and it will show the following fatal error

    dyld: lazy symbol binding failed: Symbol not found: _objc_setProperty_nonatomic

    To fix this one needs to change 1 setting.
    Select the project -> Under Targets Select cocos2d-library -> Under Build Settings find “iOS Deployment Target” by default this is set to iOS 6.0 -> Change it to iOS 5.0

    Now it will run on iOS 5.0, 5.1 and 6.0

  10. [...] You can find more details in my blog post about enabling ARC in a cocos2d project. [...]

  11. mario says:

    Hello,

    I get 11 issues with xcode 4.5.2 and ios 6. Any help …

    CCTexture2D.m
    arcEnableProject/arcEnableProject/libs/cocos2d/CCTexture2D.m:466:28: ‘UILineBreakModeWordWrap’ is deprecated: first deprecated in iOS 6.0

    arcEnableProject/arcEnableProject/libs/cocos2d/CCTexture2D.m:517:30: ‘UITextAlignmentLeft’ is deprecated: first deprecated in iOS 6.0

    CDAudioManager.m
    arcEnableProject/arcEnableProject/libs/CocosDenshion/CDAudioManager.m:402:11: ‘delegate’ is deprecated: first deprecated in iOS 6.0

    Thank you

  12. Richard says:

    I tried this tutorial and I ran into a problem with Refactoring to Objective-C ARC. It won’t do it and it says because there are 21 errors in the code. I have my project checked only and it says Fix all ARC readiness issues and try again. This is for the latest build of Cocos2D 2 and I have the Base SDK as iOS 6.0.

    • Cocos2D isn’t tested with ARC so I’m not surprised if new versions add code to the project templates that’s not compatible with ARC. Your best option is what it says: fix those issues. You can google each class of error messages you get to get help on each. With that approach it’s often relatively straightforward to make these fixes, since there’s plenty of Q&A for just about every possible ARC readiness issue.

  13. Bryan says:

    Thanks Steffen, very helpful tutorial!

  14. Butterbeast says:

    Very cool and helpful post but when I want to add to my existing project does not work.

    I film a video and can you tell me what I did wrong?
    http://www.youtube.com/watch?v=n0xna4ZAEnE

    • Butterbeast says:

      I found the solution, I copy libs folder one level to deep, I should copy it in to folder where .xcodeproj file is located.

      I lost one day but now works prfect.

      Thanks again for this great tutorial!

  15. Stiller says:

    Hi Steffen,

    Have you got this working with cocos2d 2.1 rc0a?

    I get the following error:

    cannot find interface declaration for ‘CCActionInterval’, superclass of ‘CDXPropertyModifierAction’

    And several more.

    Thanks!

    • Sounds like a header search path not set or set incorrectly for CocosDenshion (CDX* classes are CocosDenshion classes). Cocos2d 2.1 builds fine as a static library. If you want to add CocosDenshion to the static library keep in mind that the CD files are in a different folder and need to be able to find the cocos2d headers via the header search path build setting.

      • Stiller says:

        Hi Steffen,

        I have set the header search path to ./** and ensured that it is not changed to “./**/**”. Did you follow the exact same steps in this tutorial?

        Is there a github repository of ARC enabled 2.1 rc0a?

        Thanks!

      • Stiller says:

        Ignore the previous comment. I got it to work! Thanks!

  16. Geeta says:

    Thanks!!

Leave a Reply

Powered by WishList Member - Membership Site Software