Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References

by Clint on March 30, 2009

Finding an elegant way to reuse and share code (i.e., libraries) across separate iPhone applications can be a bit tricky at first, especially considering Apple’s restrictions on dynamic library linking and custom Frameworks. Most people agree that the best solution is to use static libraries. This tutorial builds on that solution, showing how your Xcode project can reference a second Xcode project–one which is used to build a static library. This allows you to automatically build that static library with the rest of your app, using your current build configuration (e.g., debug, release, etc.) and avoid pre-building several versions of the library separately (where each version was built for a specific environment/configuration).

Problem: What’s the best way to share code across iPhone projects?

If you want to reuse/share code across different iPhone applications, you only have two options (that I’m aware of):

  1. Copy all of the source code from the “shared” library into your own project
  2. Keep the shared library code in a separate Xcode project and use it to build static libraries (e.g., libSomeLibrary.a, also referred to as “archive files”) that can be referenced by your project and used via static linking.
[ad]

The first option, copying the files, should be avoided when possible since it’s inherently redundant and contrary to the goal of keeping “common code” modular and atomic. It’s a much better idea to put the code in a static library since, as mentioned in the introduction, dynamic linking to custom libraries/frameworks isn’t allowed by Apple when it comes to iPhone apps. If you’re not sure how to put your code in a static library, I’d suggest taking a look at this tutorial on the Stormy Productions blog.

So we’ve established that the second option is preferable, but there’s a catch: you’ll need to build and distribute multiple versions of the static library–one for each runtime environment and build configuration. For example, you would need to build both “release” and “debug” versions of the library for the Simulator, as well as other pairs for the iPhone or iPod device itself. How can we avoid manually pre-building and managing separate .a files?

Solution: Static libraries that are built on-demand via Xcode cross-project references

The trick to avoid pre-building static libraries for each environment is to use an Xcode “cross-project reference” so that those libraries are built dynamically (i.e., when you build your own app) using your app’s current build configuration. This allows you to both reuse shared source code and avoid the headache of managing multiple versions of the library. Here’s how it works at a high level:

  1. The shared code lives in its own Xcode project that, when built, results in one or more static libraries.
  2. You create an Xcode environment variable with a path to the directory that contains the static library’s *.xcodeproj file.
  3. All iPhone apps that need the static library will use the aforementioned environment variable to reference the library’s Xcode project, including any static library in that project and the related header files.
  4. Each time you build your project for a specific configuration/runtime environment, the shared project library will also be built for that config/environment–if it hasn’t already–and linked with your executable.

In addition to solving the main problem (reusing code and avoiding management of multiple library versions), there are a couple of nice benefits to this strategy. First, if you make changes to the shared library source code, those changes will immediately be included the next time you build your own project (via the cross-project reference). Second, you can modify the Xcode environment variable to point to different versions of any project. For example, you might have separate directories for “somelibrary-1.0″ and “somelibrary-2.0″; as you’ll see in the detailed solution instructions, it’s easy to modify the environment variable and switch your project to a different version of “somelibrary.”

Other Solutions

zerg-xcode

Victor Costan has developed a slick command-line tool called “zerg-xcode” which helps you copy the source code from one Xcode project (i.e., a static library project) into another Xcode project. In addition to physically copying the files, it inserts the targets from the “library” project into your “app” project. If the library project changes, you simply run zerg-xcode again with the approriate commands to sync the files and targets. Some people may find this tool very useful; my personal preference, however, is to avoid making any copies of the source code files and stick to Xcode’s built-in “cross-project reference” mechanism.

“Fat” Universal Binary

Another approach is to “bundle” two versions of a static library into a single file, referred to as a “fat” universal binary (see this post on the Latenitesoft blog for an example). More specifically, one version of the library would be for the i386 architecture (i.e., the Simulator) and the second for the ARM architecture (i.e., the phone). This may be a perfectly fine solution for you if you really only need two versions, or if the source code for the library is kept private. That said, you’re still left with the task of maintaining pre-built versions of the libraries (plus the extra work of bundling them into the single file). In addition, I’m not sure that you can bundle more than two versions of the library into the binary (e.g., iPhone “release” and Simulator “release”, but not iPhone “debug” and Simulator “debug”).

How to Implement the Cross-Project Reference Solution

The instructions for setting up cross-project references to shared static libraries can be split into two parts:

  • Part 1: Global Xcode Settings
  • Part 2: Project-Specific Settings

Also, I’ll be using an example in the instructions to help illustrate things. A suitable example would be an application that needs to use a shared static library from a separate project. In this case, I’ll use a sample iPhone app called “Game Skeleton” (by Matt Sephton) that depends on a static library called libcocos2d.a (which is part of an open source project called Cocos2d-iphone).

Note: If it wasn’t already clear, cross-project referencing is a standard Xcode feature and is actually suggested by Apple in the official “Xcode Project Management Guide” documentation. You can certainly get some great bits of info from Apple’s guide, but as you’d expect, it’s a high-level document (hence my thinking that this tutorial could be helpful for others).

Part 1: Global Xcode Settings

The first step in getting your Xcode project to use cross-project referencing is to configure a couple of things that aren’t specific to any one project (i.e., global settings).

Set up a shared build output directory that will be shared by all Xcode projects.

Screenshot showing how the Xcode preference dialog and how to configure Xcode to use a global build output directory.

Screenshot showing how the Xcode preference dialog and how to configure Xcode to use a global build output directory.

  1. With Xcode open, select “Xcode > Preferences” from the menubar.
  2. Select the “Building” tab.
  3. Set “Place Build Projects in” to “Customized location” and specify the path to the common build directory you created.
  4. Set “Place Intermediate Build Files in” to “With build products.”

Why is this necessary?

A brief explanation of why this is necessary might be helpful for some people. When you build your app (i.e., Xcode project) Xcode generates one or more “products” (object files, libraries, etc.) in the project’s own build output directory, by default; it will then “look” inside this directory when it comes time to link everything together and make an executable, for example.

Once you start using cross-project references, you’ll essentially be building more than one project. However, Xcode will still only look in the immediate project’s build output directory for libraries. Apple therefore recommends using a shared build output directory for cross-project references (see the last paragraph in the “Referencing Other Projects” section of “Xcode Project Management Guide: Files in Projects”). This ensures that Xcode will always be able to find products from other projects builds.

Will a shared build output directory cause problems?

I’ve had some questions from folks about whether or not using a shared build output directory causes problems. While I’m certainly not an authority on building with Xcode, I can say that in four months of using this technique (with several projects and a few different shared libraries) I’ve not had any problems (such as a “debug” build resulting in a “release” version of your library being overwritten, etc.).

Apple’s Xcode documentations clearly states that “Within the build directory, Xcode maintains separate subdirectories for each build configuration defined by the project” (see the “Build Locations section of “Xcode Project Management Guide: Building Products”). For example, I have a custom logging library that is used by multiple iPhone and OS X apps. The OS X versions of the *.a file show up in “Release” and “Debug” sub-directories within the common build output folder, the simulator versions in “Release-iphonesimulator” and “Debug-iphonesimulator”, and finally the device versions in “Release-iphoneos” and “Debug-iphoneos.” In other words, none of the builds seem to be overwriting each other.

Add a “Source Tree” variable that Xcode can use to dynamically find the static library project.

“Source Tree settings” are basically Xcode environment variables that hold paths to directories on the file system; this allows us to make the cross-project references flexible and avoid hard-coded paths.

Screenshot showing the "Source Tree" settings tab within Xcode preferences.

Screenshot showing the "Source Tree" settings tab within Xcode preferences.

  1. Again, open the Xcode preferences.
  2. Select the “Source Trees” tab.
  3. Create a new Source Tree variable by clicking on the “+” button and filling in the columns. The screenshot above shows that we’re using “COCOS2D_SRC” for the cocos2d-iphone variable name and that it points to “/Users/clint/dev/cocos2d-iphone.googlecode.com/release-0.5.3″.Tip: avoid using special characters in the actual file path (i.e., stick to alphanumeric characters, underscores, and hyphens); this path will be used as a “Search Path” and Xcode seems to have problems with search paths that use characters like an ampersand (&).

Part 2: Project-Specific Settings

Once you’ve got Xcode configured to use a global build output directory and have a “Source Tree” variable pointing at your shared project, you’re ready to set up the cross-project reference, dependencies, etc.

Set Up the Cross-Project Reference, Header File Search Paths, and Static Library Linking

  1. Open your project in Xcode.
  2. In the “Groups & Files” pane of Xcode, select your project root and hit Option+Cmd+A (add to project).
  3. Find the Xcode project package for the project that contains the shared library. Using our example, we’ll select the Cocos2d-iphone Xcode project (cocos2d-port.xcodeproj):
    Screenshot showing a second Xcode project file being selected so that we can add a reference to it.

    Screenshot showing a second Xcode project file being selected so that we can add a reference to it.

  4. When the “Add to Project” dialog is displayed, use the same settings displayed in the screenshot below and click the “Add” button.
    Important: do NOT check the “Copy items” box.

    Screenshot showing which "add to project" options are selected when adding a cross-project reference in Xcode.

    Screenshot showing which "add to project" options are selected when adding a cross-project reference in Xcode.

  5. After you click the “Add” button the project will appear as a “sub-project.” In our Cocos2d-iphone example, it looks like this:

    Screenshot showing how the Cocos2d-iphone Xcode project appears as a "sub project" once it has been added to the main "Skeleton" project.

    Screenshot showing how the Cocos2d-iphone Xcode project appears as a "sub project" once it has been added to the main "Skeleton" project.

    Remember that you have not imported a physical copy of the second project–it’s a reference.

  6. When the cross-project reference appears select it and hit Cmd+i. Then change “Path Type” to be relative to the environment variable you set up in Part 1. In the example below, we’re using the COCOS2D_SRC variable:

    Screenshot showing the Xcode "Project Info" dialog for a project added via cross-project reference.

    Screenshot showing the Xcode "Project Info" dialog for a project added via cross-project reference.

Configure the Library Dependencies, Linking, and Header Files

  1. In the “Groups & Files” pane of Xcode, under “Targets”, select your main app target and hit Cmd+i. Then select general tab and add the static library(ies) your app needs from the shared project by clicking the “+” button under “Direct Dependencies”. In our example, we’ve added the “Chipmunk” and “cocos2d” libraries which are both built from the Cocos2d-iphone project:

    Screenshot showing an Xcode executable target being configured to depend on static libraries that are built from a cross-project reference.

    Screenshot showing an Xcode executable target being configured to depend on static libraries that are built from a cross-project reference.

  2. Click on the build tab and scroll down to the “search paths” section
  3. Important: If a hard-coded path to your shared project appears in the “Library Search Paths” field, delete it. This can be done by double-clicking the field and using the “-” button.
  4. Double-click on blank area next to “User header search paths”. Then click on the “+” button, check the recursive checkbox, and type in the Xcode environment variable that points to your shared project directory, surrounded by $(). The example screenshot below shows $(COCOS2D_SRC) being used:

    Screenshot showing how to configure the Xcode "User Header Search Paths" for a library that is being included via cross-project reference.

    Screenshot showing how to configure the Xcode "User Header Search Paths" for a library that is being included via cross-project reference.

  5. When you click OK and go back to the Build tab, the “user header search paths” text field should show an absolute path to your shared project directory. In our example, $(COCOS2D_SRC) expanded to the actual path and ends with “**” to show that the search will be recursive:

    Screenshot showing how an Xcode environment variable will be dynamically expanded to the actual, absolute path once entered using the $() notation.

    Screenshot showing how an Xcode environment variable will be dynamically expanded to the actual, absolute path once entered using the $() notation.

  6. Finally, click and drag the static libraries from underneath the cross-project reference to “Targets > {your target} > Link Binary with Libraries.” This ensures that that the .a files will be passed to the linker when you do the build. Here’s a sample screenshot from our example app:

    Screenshot showing how to link your executable to the static libraries via cross-project reference in Xcode.

    Screenshot showing how to link your executable to the static libraries via cross-project reference in Xcode.

Summary

To recap, if you need to share code across different iPhone projects I suggest 1) putting the shared code in its own “static library” Xcode project and 2) using a cross-project reference so that you can build the library with your own app as needed. The verboseness of this tutorial might give you the impression that setting this up is a lot of work; it’s not, really, especially if you do it more than once (which is likely, considering that the goal here is to share code across multiple projects). I’ve been using this approach for about four months with several projects and it’s definitely saved me a lot of time. Finally, there might be a better strategy that I’m not aware of; feedback and suggestions for alternate solutions are certainly welcome.

Clint Harris is an independent software consultant living in Brooklyn, New York. He can be contacted directly at ten.sirrahtnilc@tnilc.
  • http://blog.costan.us Victor Costan

    Dear Chris,

    Thank you so much for your post!

    I wasn’t completely happy myself with copying files between projects, and I was researching using hardlinks or symlinks instead of copies.

    That aside, I’m wondering how you would advise to apply your method in an environment where source code is under version control, and developers can check out the code at arbitrary locations on their filesystem.

    Thanks!
    Victor

  • http://www.clintharris.net Clint

    @Victor Costan: Thanks for the feedback! Good question regarding using this method in a team environment with source control. In a nutshell, it seems to work just fine–I’ve personally used this strategy on projects with more than one developer, where each developer checks out the code to an arbitrary filesystem location. Neither the “shared build output directory” nor “environment variable” settings (as described in “Part 1. Global Xcode Settings”) are stored in the *.xcodeproj package that usually goes into source control. Each developer will configure these settings for his/her own instance of Xcode.

    In the example I use in the tutorial, the project.pbxproj file (i.e, the main Xcode project meta-data file inside the *.xcodeproj package) only contains references to the COCOS2D_SRC variable; the actual path to the directory where I’m keeping the cocos2d project doesn’t show up in the file. Similarly, my shared build output directory doesn’t appear in the project.pbxproj file, either. Those global settings are only stored on my machine and don’t go into source control.

  • Steve Johnson

    Hi Clint – thanks for the article. I also have a question relating to multiple developers with different checkout structures.

    In our case, our common library root folder will always be a sibling of our parent folder. So:

    Developer/svnroot/trunk/common/mylib is where the library project will be.
    Developer/svnroot/trunk/apps/myapp is where the app project will be.

    Couldn’t I specify “relative to project” for all of my path settings and not need to use the Source Paths or Environental Setting? This way, once a project is set up, the other developer only needs to check out at “trunk” and all is well??

    I haven’t tried any of this, just trying to sort it out ahead of time.

    Thanks,
    Steve

  • http://www.clintharris.net Clint

    @Steve Johnson: I totally agree with you. In a scenario where the relative path between the “project A” and “project B” is constant on everyone’s machine (e.g., both projects are part of the same version control checkout) you should be fine with using the “relative to project” setting for the project reference (i.e., as opposed to “relative to SOMELIB_SRC”).

    Thanks for pointing this out–could be really helpful to some folks.

  • Sean

    Perfect, Worked like a charm. I don’t have to keep flipping back and forth between builds it automatically builds the right library for my target. You are going to save me a lot of time.

  • http://www.paulsolt.com Paul Solt

    Thank you, I’ve mostly worked with Visual Studio and was looking to do something like this in Xcode for the iPhone. Your guide is a good reference.

    I’m using the setup with multiple targets that use different versions of a library and it’s nice to have everything build and link properly.

  • http://www.spy.org Scott D. Yelich

    Working my way through this… I’d also like to get to the point where just adding the libX.a to a project is as simple as shown in the facebook connect demo video. I understand here that we’re building the lib each time… so this is good for when that is needed.

    Step 5:
    When you click OK and go back to the general tab, the “use …
    perhaps:
    When you click OK and go back to the *build* tab, the “use …

    ok, yup… build > clean all targets on the static shared lib xcode project and build clean on test project … build and go on test project built the static library (although I had to update the static lib xcode before the libX.a went from red to black) — I just switched from device to simulator — it seems both get built (even when just building the test app for the simulator).

    Thanks!

  • http://www.clintharris.net Clint

    @Scott D. Yelich: Thanks for the feedback! I’ve updated the post with your proposed edit for Step #5 (good catch!).

  • http://www.notionforge.com Santthosh

    Thank you very much, I was also not happy replicating code and this approach came in very handy. I actually used Keremk’s iPhone Static Library project template to build the static library, this reduced the trouble in setting up the common library.

  • ramzez

    Hi, is there a way to share Macros across the project as well?

  • http://warpedvisions.org/2009/05/14/xcode-static-libraries-and-cross-project-references/ warpedvisions.org :: Link: XCode Static Libraries and Cross-Project References

    [...] XCode Static Libraries and Cross-Project References, a step-by-step guide covering methods for creating and using static libraries in XCode projects. window.onload = function(){prettyPrint();}; [...]

  • http://www.clintharris.net Clint

    @ramzez: Yes–you can share macros the same way you would in any other situation (e.g., by putting something like “#import file_with_macros.h” in your code). For example, I have an Xcode project for a custom logging tool I made; the project is built into a static library and there are also a few macros defined in some of the header files. All of my apps which reference the logging project (using the steps in the tutorial) can use those macros as long as I #import the correct header file. In my case, I use the logging macros everywhere so I #import the logging header in each project’s .pch file (i.e., every file in the project has access to the logging header and the macros it defines).

    In other words, if you just want to share C macros there’s really no need to go use the approach described in the tutorial.

  • ramzez

    @Clint, hmm, we thought about it however our code base is about 20 years old and modifying thousands of files to just include a header file with macros is not really a solution for us.

  • Max MacLeod

    Thank you so much Clint. This has saved me days of frustration and pain without a doubt. You are the man!

  • http://www.letstalkiphone.com Kyle Davis

    Wow, this is unbelievably useful. Thanks for this!

  • http://www.mozartbrain.com frankmail007

    Great article. But I have problems. Here is my description:

    My project structure:

    Projects—CompanyName—externalLib
    —lib
    —project 1
    —project 2

    First of all, I didn’t set source tree because I’m using relative path and I didn’t set the shared output path because I’ll set the build path to different companyName’s lib. I followed every other things in your article.

    My problem is I still get the link error to link to my externalLib. The dependency check works and external lib is built inside the lib directory. But the funny thing is the library for example libexternal.a is always shown in red color. It looks like it has never been built. I think that’s why I got the linkage errors. But I don’t know what happen? Do you have any clue.

    Thanks very much,

    Frank

  • http://www.letstalkiphone.com/2009/05/19/tic-tac-toe-in-cocos2d/ Let’s Talk iPhone » Tic Tac Toe in Cocos2D

    [...] tutorial, or, even better, set it as a “build on demand” static library as shown in this excellent article.  Either way, you’ll need a Cocos2d project that builds and runs (even though the app, at [...]

  • ramzez

    My biggest problem with Xcode is freezing and slowness. what i have is a project which has 39 static libraries defined as targets from on big source tree. I build for iphone. Each time i start Xcode or change between Simulator or Device it takes ages on Checking Dependencies stage and then starts to recompile all the libraries, although they are all built already.

    If anyone knows a solution to this, i would be really grateful.

  • ramzez

    @frankmail007

    try hitting Cmd+I and see what the path it things the red coloured library should be…

  • Max

    Hi Clint,
    got a question for you. Assume I have three static libraries, A, B, and C.

    A depends on B, and B on C.

    In xcode, assume I have project A open.

    It seems I also need to have B and C as subprojects.

    I would have hoped that I just need B. That it would know that B has a dependency on C.

    Any thoughts?

    Cheers,
    Max

  • Max

    OK I think I have figured this out. I need to point to both B and C.

    By the way I have encountered a bizarre problem. When I mark the static library to include “recursive” in the user header search path, sometimes it doesn’t find it.

    I mark that entry non-recursive, and it finds it ok.

    Only seems to happen with one library.

    Quite strange. Must be a good reason for it…

  • http://www.silicon-studios.com Nonnus

    hi,

    awesome piece of info you got here !
    i got lost for a while until i remembered i had spaces in some folder names on the shared build path so all worked seamlessly as soon as i unescaped them, i hope this tip is helpful for anyone in same situation

    i am just missing having the header files available on the target app using the library,
    what is the best way to have them available like the sdk framworks do ?

    abraços

    nonnus

  • Alexei

    I have tried this approach and while it builds just fine, I am running into a weird problem with some of my methods optimized out when the library is compiled. So, when I run the app, it throws an unrecognized selector exception.

    Any ideas?

  • http://blog.costan.us Victor Costan

    @Alexei: try adding -ObjC to “Other Linker Flags” in the Build options for the binary (not necessary for the library).

  • Alexei

    Yes, -ObjC worked. Thanks a lot!

  • http://www.creativeclasssoftware.com David Roach

    I love this article, great job!

    I have two such libraries that I have developed and this method is similar to that of Visual Studio.

    My question to you is, is there a way that if you are doing adhoc development of a library at the same time you are developing an application, can you have both source trees appear in Xcode. Right now all you get is the lib reference.

    Kind regards

    David

  • Max

    Hi David,
    I reckon you could just import the other source. Then set up two different targets in your workspace. One to generate your static library and the other to generate your executable.

  • http://www.iphonearch.com Iphone Architect

    nice tutorial, thanks
    i’ll try to implement Victor’s solution with zerg-xcode

  • Paul

    Thanks for the great tutorial!

    One note from my own experience was that to use some of the Dynamic Binding capabilities of Objective-C (in particular the NSClassFromString method) it was necessary for me to include the -ObjC compile flag in the build settings of both targets.

    I also had two questions: 1) What is the best way to share a CoreData project as a library between multiple projects?

    2) Is there any way to share NIB’s between multiple iPhone projects?

    Thanks again,

    Paul

  • http://www.logikstate.com Paul Carter

    This is fantastic!

    I would never have figured out how to do this without this tutorial.

    Many many thanks

    Paul.

  • http://www.lbtechservices.com/blog/2009/07/16/sharing-code-in-iphone-applications/ LB Technology Services Blog » Blog Archive » Sharing code in iPhone applications

    [...] has to be. I was having some trouble yesterday with one project and found this great article, Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References … other posts by [...]

  • Mathieu

    Hi Clint! That’s an awesome tutorial, thanks an lot.
    I’m just a beginner at iPhone / Xcode programming and I managed to implement all what you described.

    However, I still have a problem I can’t figure out. It’s about headers importing… Well I try to import cocos2d.h in a .m file, but then the project won’t build (“no such file or directory”).
    It seems that Xcode refuses to actually search into my user header path.

    I tried #import and #include, and “cocos2d.h”.
    I used the source tree variable (recursive) for “User header search path” and “Header search path” in project and target preferences, for all debug and release configurations…

    Not working…

    I tried to address the complete absolute path directly in the import and then it works, but all subsequent headers are then not found.

    If I copy the header file in my classes path, it is found, but same error, all other subsequent headers are not found.

    I verified the path I entered for COCOS2D_SRC and it fits with the actual path so I’m running out of solutions…

    Well I’m becoming crazy now, so if someone can help!

    Regards,

    Mathieu

  • http://mitchallen.com/iphone/archives/254 Cocos2D Game Engine

    [...] http://www.clintharris.net/2009/iphone-app-shared-libraries/ – a general article on iPhone shared libraries [...]

  • http://maniacdev.com/2009/07/11-cocos2d-iphone-game-engine-resources/ 11 Cocos2D iPhone Game Engine Resources | iPhone Development Tutorials and Tips

    [...] iPhone App Shared Libraries http://www.clintharris.net/2009/iphone-app-shared-libraries/ – A good tutorial for using [...]

  • http://web.mac.com/dbolli Derek Bolli

    Hi Clint,

    Thanks for the great article, I have successfully repeated the steps above with the latest cocos2d-iphone-0.8-rc2. I didn’t need the shared build output directory step as I am happy to re-build the cocos2d project from time to time but the above will save me a great deal of time when updating my cocos2d-iphone projects when new releases are updated (which is often thanks to the pace at which cocos2d-iphone team is developing the product).

    With regard to Mathieu’s question above, I had the same problem and it was due to spaces in the path in the COCOS2D_SRC source tree xcode preferences setting (as mentioned in the article in the source tree variable tip) which I solved by adding a relative path i.e. ../cocos2d-iphone-0.8-rc2 rather than /Path/to/my/dev/dir with spaces/cocos2d-iphone-0.8-rc2. Have a look in the build commands transcript area of xcode project Build Results and you’ll probably see a mangled path e.g. -iquote /Path/to/my/dev/dir -iquote with -iquote spaces/cocos2d-iphone-0.8-rc2. If your xcode project folder is in the same dir as cocos2d-iphone-0.8-rc2, you can use a relative path as above.

    Thanks again for the great article :)

    Regards,

    Derek Bolli, Head Hacker,
    Bolli World HQ Computing Facility,
    North Sydney NSW 2060
    Sydney, Australia email: dbolli at bigpond.net.au (home)

  • https://extranet.akqa.com/collaboration/display/mobile/Development+Architecture+%28TRUECITY%29+-+Draft Confluence: AKQA Mobile

    Development Architecture (TRUECITY) – Draft…

    Development Architecture  This section covers the development architecture of the Nike TrueCity project. The scope of this document includes: Testing framework (e.g. unit tests) Build architecture (e.g. autobuild,……

  • https://extranet.akqa.com/collaboration/display/mobile/Non-Functional+Architecture+%28TRUECITY%29+-+Draft Confluence: AKQA Mobile

    Non-Functional Architecture (TRUECITY) – Draft…

    Development Architecture  This section covers the development architecture of the Nike TrueCity project. The scope of this document includes: Testing framework (e.g. unit tests) Build architecture (e.g…….

  • tonton

    that ‘s a great job , thanks for all your job
    fyi i had some problems with the intermediate build path (xcode global settings) then i put the same absolute path (= build product location )

    when using that config i dont need step 6 (Finally, click and drag the static libraries)

    is it a better way or i missed sthg?

  • http://mitchallen.com/iphone/archives/266 Running the Cocos2D examples

    [...] Then I’d recommend reading up on shared libraries: http://www.clintharris.net/2009/iphone-app-shared-libraries/ [...]

  • http://onewiki.yellowpages.com/display/~bbrooks/Brad+Brooks Confluence: Brad Brooks

    Brad Brooks…

    iPhone Dev Links Fast UITableView Scrolling…

  • http://web.mac.com/dbolli Derek Bolli

    Hi Clint, just an update to say that your tutorial saved me more than an hour today updating my cocos2d xcode projects from v0.8-rc2 to v0.8. All I had to do (after I’d downloaded and expanded cocos2d v0.8 into the same parent folder as my xcode project folders) is:
    Edit Xcode->Preferences->Source Trees->Path from ../cocos2d-iphone-0.8-rc2 to ../cocos2d-iphone-0.8
    Delete linked project cocos2d-iphone-0.8-rc2.xcodeproj
    Project->Add to Project cocos2d-iphone-0.8.xcodeproj from ../cocos2d-iphone-0.8
    Add cocos2d Direct dependencies in Target->General tab
    Drag static libs from under cocos2d-iphone-0.8-rc2.xcodeproj to Target->Link binary with Library
    Clean All
    Build and Go

    Great work, thanks again :)

    Derek Bolli, Head Hacker,
    Bolli World HQ Computing Facility,
    North Sydney NSW 2060
    Sydney, Australia email: dbolli at bigpond.net.au (home)

  • Jayant

    Wondering if anyone has had success getting Categories to work. So I have ‘MyStaticLib’ (Cocoa Touch Static Library) project which is referenced in ‘UsingMyStaticLib’ (View-based application) project, using the steps in this post.

    MyStaticLib: TestClass & NSObject+MyCategory with (void)time & (void)printTime respectively.

    In ‘UsingMyStaticLib’ I reference ‘MyStaticLib’ and reference the 2 header files. My test code:

    TestClass *test = [[TestClass alloc] init];

    if ([test respondsToSelector:@selector(printTime)]) {
    NSLog(@"ok we're in business!");
    [test printTime];
    }
    else {
    NSLog(@"sorry, no go!");
    [test time];
    }

    [test release];

    The code above always goes to the ‘else’ block and prints the time using the TestClass’s own selector. If I remove the conditional block and call the printTime method anyways, the app crashes.


    UsingMyStaticLib[959:20b] *** -[TestClass printTime]: unrecognized selector sent to instance 0xd17570
    UsingMyStaticLib[959:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[TestClass printTime]: unrecognized selector sent to instance 0xd17570'

    Any ideas on what I might be doing wrong? Please help!

  • Jayant

    The -ObjC option in ‘other linker flags’ solved the issue, thanks to ‘Victor Costan’ for that. And thanks to Chris for this awesome article. Cheers.

  • http://beta.letstalkiphone.com/2009/05/tic-tac-toe-in-cocos2d/ Let's Talk iPhone » Tic Tac Toe in Cocos2D

    [...] tutorial, or, even better, set it as a “build on demand” static library as shown in this excellent article.  Either way, you’ll need a Cocos2d project that builds and runs (even though the app, at [...]

  • http://www.seqoy.com SEQOY

    One nice tip: If when you import the .xcode project to your own project.

    All the links are broked (red). Probably you forget to build all the libraries on the project your are importing.

    Work for us. All the best.

  • Brad Parks

    For anyone who’s interested in implementing this with Cocos2d, a user on the cocos2d forums (thanks tjweir!) put together a nice project template with this already integrated

    http://github.com/tjweir/cocos2d-application/tree/master

    Brad

    PS: The thread I found it in is here:

    http://www.cocos2d-iphone.org/forum/topic/213#post-1155

  • ramzez

    how to share pre-processor definitions (macros) across different projects? i.e. if i want to setup pre-processors only in root project but so that they are picked up by static libraries projects?

  • http://mitchallen.com/iphone/archives/304 Getting Started with the Cocos2D Game Engine
  • BG

    Very helpful!

    FYI: While doing this, I had a weird issue with a missing symbol (___restore_vfp_d8_d15_regs) that I resolved by compiling the library with GCC 4.0 instead of GCC 4.2. This was on Xcode 3.2, OSX 10.6, iPhone OS 3.1.

  • Michael

    I tried using this method with the facebook-connect iphone library but am having some issues. What I’m doing is simply opening a facebook session and attempting to display the login dialog. This works fine when I import the facebook source code directly into the project. With the project-reference approach, everything compiles and links fine. But when I try to run, no dialog. Any idea what might be going on? Thanks for the excellent article.

  • http://galileo-app.com Evgen Bodunov

    There is more simple way to do that:
    1. add reference to xcodeproj file in your project (in Frameworks for example)
    2. double-click on target and open general tab
    3. add library bundle target in direct dependencies list.
    4. drag and drop libLibName.a from xcodeproj reference (in you Frameworks) to “Link Binary with Libraries” folder of your target.

    that’s all.

  • http://galileo-app.com Evgen Bodunov

    oh. i miss step 5.
    5. in project configuration add path to your library headers into variable “user headers path”

  • http://confluence.intranet.tat.se/display/~petil/Notes+on+getting+started+with+Cascades+in+XCode Confluence: Petter Tiilikainen

    Notes on getting started with Cascades in XCode…

    TestSuiteApp (runs in X11): CascadesTestSuite/targets/macos Cocoa Cascades Viewer including Cascades trunk:…

  • Tony John

    Really helpful.

    Is there any way to set break points in side the static library project so that we can debug it. What happens when the project gets built, first it builds the library and makes .a file out of it. So XCode ignores the break points. How do we debug the cross referenced project?

  • http://blog.costan.us Victor Costan

    I figured out how to build static libraries that package the simulator and device code into a single file. This can come in very handy when distributing your static libraries. Read my blog post for details.

  • http://blog.costan.us Victor Costan

    @Tony: that’s one of the reasons why I include the library source code in my application projects. You can read about my method in this blog post.

  • http://mycodestudio.com/blog/2009/12/06/cocos2dpt1/ cocos2d Part1 « myCodeStudio
  • http://ghosthandgames.com/ chief

    Just wanted to thank you for this article. I hit a few snags, but worked through them. If your Source Tree’s path includes spaces you have to quote it (“Users/chief/iPhone Projects/test”). Otherwise this worked like a charm. Thanks again for sharing!

  • Martin Kovachev

    We are using pretty much the same type of technique over here to handle a shared part of a mac / iphone application – all in a single static library.

    So far it was running ok, but recently we’ve moved to Snow and the new SDK’s and we found the need to use Universal binaries to ship 32/64 binary in a single package.

    What we did is select universal binary project option in both the static library – and the project that uses it itself.

    Both the project and static library have two profiles – Release / Debug (I am assuming that when i build the project – the static library is somehow – magically switching to the same profile as the project itself, because there are no options to select this within the project – for a specific static library project attached to it).

    The problem is that when building starts – we get that static library blablabla – is of an incompatible architecture.. duh? Wasn’t it supposed to build all necessary linking objects for an universal binary and figure out a way to link them?

    Anyone having the same problem?

    How do you build an universal binary with static libs attached to the project?

  • http://defree.co.kr/blog/?p=611 Samuel's Project Nash » Blog Archive » ????? iPhone ?? ??? 1 – Cocos2D for iPhone ??

    [...] http://www.clintharris.net/2009/iphone-app-shared-libraries/ – a general article on iPhone shared libraries. [...]

  • http://www.mattsoftware.com/wordpress/2010/01/09/iphone-development-and-code-reuse/ iPhone Development and Code Reuse « mattsoftware

    [...] Easy, Modular Code Sharing  Across iPhone Apps: Static Libraries and Cross-Project References [...]

  • http://visualrinse.com/2010/02/02/links-for-2010-02-02/ links for 2010-02-02 | Visualrinse | Design and Development by Chad Udell

    [...] Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and … Finding an elegant way to reuse and share code (i.e., libraries) across separate iPhone applications can be a bit tricky at first, especially considering Apple’s restrictions on dynamic library linking and custom Frameworks. Most people agree that the best solution is to use static libraries. This tutorial builds on that solution, showing how your Xcode project can reference a second Xcode project–one which is used to build a static library (tags: iphone_development cocoa) [...]

  • Quentin

    Does anyone have it working with Xcode 3.2 ? ’cause i remember i had it working months ago, but not anymore.

  • http://web.mac.com/dbolli Derek Bolli

    @Quentin
    I updated my linked Xcode project with cocos2d-9.0-beta2 and it compiles using Xcode 3.2.2 with the iPhone 3.2 iPad beta

  • Quentin

    Hello,

    Ok, wrong try from me. I think i had something “broken” in my project paths, because i created a new project and it works now.

    Thank you for your quick reactions guys.

  • http://www.inadaydevelopment.com/ Kenny Wyland

    I want to have your babies. I’ve tried a couple of other tutorials on how to get this working, but they’ve never worked for me. Not only is this one working, but the instructions were far more simple than the other sites!

    Thank you!
    Kenny

  • http://www.inadaydevelopment.com/?p=140 In A Day Development » Blog Archive » Using another XCode Project as a Static Library

    [...] Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References [...]

  • http://gordonknight.co.uk/wordpress Derek Knight

    Great tutorial. I’ve been using XTool for two weeks now and am having a lot of minor problems (I have used Visual C for 20 years!). Tutorials like your, which are so clear and easy to follow and a god-send.

    Thanks a lot
    Derek

  • http://gordonknight.co.uk/wordpress Derek Knight

    Twit, Derek. You can probably figure out what I meant. “Tutorials like yours, which are so clear and easy to follow are a god-send”. Doh!

  • http://iamtyler.com/2010/04/static-libraries-in-xcode/ Static libraries in Xcode « I am Tyler

    [...] the end, I found some help in a blog post from Clint Harris on the subject. I haven’t actually put it in place yet, but I’m assuming it’ll [...]

  • http://www.Pixels4Charities.com Pixels 4 Charities

    Hi, I can’t quite seem to figure out how to include and access a function in the static library. I followed the steps perfectly and the application builds fine (without any calls to the library).

    But now I want to actually call something and it says “TestLib.h: No such file or directory”

    I tried #import, #include, , “clsTestLib.h” and every combination. I even added the the -ObjC and -all_load Linker flags to the Project BUILD settings and no luck.

    Any ideas?

  • http://www.Pixels4Charities.com Pixels 4 Charities

    I had a user error. The tutorial is awesome but I guess I did something incorrectly. After no luck, I decided to create a new project and re-follow the steps. This time is worked out great. FYI for others who might not know, this should work with:

    #include “clsStaticLib.h”

    if you followed the steps correctly.

    Thanks again!

  • Dean P

    First off I’d like to join everyone else in commending and thanking Clint for producing a well written and concise article that has helped us all greatly.

    Next I’d like to pose a question, to both Clint and others, regarding the role of headers. From my understanding there are 3 options, Project, Private and Public. The first ‘does as it says on the tin’ making a header only accessible to the project code (that within the static library) therefore omitting it from being copied over in the build process. The result is that the project (our app) that uses the static library won’t have access to them. The second two options both copy over the header(s) and only differentiate by where they are copied to using the build settings PRIVATE_HEADERS_FOLDER_PATH and PUBLIC_HEADERS_FOLDER_PATH respectively. The Apple documentation on the matter seems to suggest this is a way of suggesting those headers ready for end user use and those currently in development that should perhaps be restricted to either ourselves or our direct collaborators.

    Having the followed the tutorial with great success I gather using the Xcode environment variable and the recursive option will provide us access to both ‘types’ of headers unless we pick to place either of them in an obscure location outside of the path covered by the environment variable (bad idea).

    So what, if any, strategies do people use to exploit some of the functionality we could gain from differentiating between the private and public headers of our static library? For instance is it possible to leverage this in such a way that only certain parts of our code using the static library have access to the private headers? Could this be achieved with a more descriptive (but less enforced) paradigm by which including a header requires specifying the final folder of the path. e.g.

    #include “private/foo.h”
    #include “public/bar.h”

    Therefore any file/code/object in our app *could* use a private header, but we would be aware we were doing so at the point of import.

    Thoughts fellow iPhone-ians?

  • Dean P

    As an addendum, it seems that regardless of the role set for a header all headers remain accessible to the code that uses the static library. For instance using the procedure outlined by Clint, try adding to the static library three headers, each with a simple macro, each marked as having one of the three different roles (project,public,private). e.g.:

    myPrivateHeader.h (role is private)
    … containing …
    #define myPrivateMacro(i) (i + 1);

    My understanding was that code outside of the project would only have access to private and public marked headers and only then based on how the header search path aligned with the relevant HEADERS_FOLDER_PATH. Project marked headers remained accessible only to the project in which they’re declared (i.e. the static library project). However from my app, I can quite happily execute the macro declared in the header marked with role ‘project’ in my static library:

    myProjectMacro(10)

    Is this because using a cross-project reference makes the ‘project’ the one using the static library, not the one containing the it?

  • MS

    This is a great guide, thanks. But one problem I noticed after setting up a shared project directory as suggested has to do with my unit testing targets.

    I have a static library project with a unit testing target that is run whenever the project builds.

    I have an application project that has its own unit tests and a cross-project reference to the static library project.

    With a shared build directory, when I build my application project, the static library’s unit testing target actually runs the unit tests from the application project, which results in the application project’s unit tests being run twice, and the static library tests are never run.

    For now I’m using separate build directories and have not seen any problems (though I’m only coding and compiling at this point, not running anything in the simulator yet, or doing any release builds). So I’m curious to know when I’ll have the problem that Xcode won’t “be able to find products from other projects builds.”

  • Mike

    I just wanted to say thanks! I didn’t want to use their template but was having issues using the cocos2d in my existing project and this helped greatly.

  • http://www.learn-cocos2d.com GamingHorror

    I made a cocos2d Xcode Project Template partially based on this article and of course using the latest cocos2d version (0.99+). Then i added a ton of other features (various build configs, IPA building, proper debug stripping, targets for debugging memory crashes, etc). All the things i need for my professional Xcode project work on a daily basis.

    The result is a 100+ page cocos2d Xcode Project setup Tutorial:
    http://www.learn-cocos2d.com/knowledge-base/tutorial-professional-cocos2d-xcode-project-template/

    I hope you don’t mind the shameless plug.

  • http://wp.kimptoc.net/?p=58 How to setup Xcode to share code across iPhone projects « Kimptoc
  • B2

    Nice article, and I went through the same issues about the same time you did. Here is the problem I’ve just discovered.

    I am using xcodebuild. My app has PRODUCT_NAME set to a user-defined build setting, MY_NAME.
    Its target has a project reference to the project that builds my static lib ORIG . When xcodebuild is launched with:
    xcodebuild -configuration … MY_NAME=foo
    it looks for libMY_NAME.a instead of libORIG.a, doesn’t find it and rebuilds the static lib as libMY_NAME.a

    This is happening because PRODUCT_NAME is being used by the static lib target to build its output name and it is getting overridden.

    Any idea about how to stop this from happening? I’m losing all the advantages of a static lib just because I want to vary my app name at build time.

  • Michael

    Fantastic article. Thank you so much for taking the time to write and share this information. Until now I’ve never been very aware of what static libraries are and how to properly integrate them.

  • Joe Falo

    Great tutorial, Clint. It worked initially but then I ran into the same problem that Mathieu ran into. This especially became a problem when I have a static library that uses another static library (both of my own making). I read somewhere else about the solution being to change the name of the project directory. This also worked initially but at some point, adding files, etc. it gets stuck… “No such file or directory”. You change the name of the library’s directory and set the Source Trees environment variable to match, it works. Only to break later when adding more files to the project. And curious enough, once it breaks on a directory name, you can’t use it again: you have to pick something new. I know it sounds crazy. I can only think that there is something in the project that gets corrupted. I am following instructions to the letter. I’d love to use this technique instead of copying files around. If anyone has a clue about this, please let me know. P.S. I’m fairly new to Apple computers and iPhone development.

  • http://ivanceras.blogspot.com lee

    Hi,
    I see that the article focus on sharing code between iphone apps, is there a way to do this on projects between iphone apps in which the same source code will also be used in a custom command line project in cocoa OSx?

  • http://www.MarkDonohoe.com MarqueIV

    Ok… I’ve got a tough one. The app compiles just fine and runs just fine… until I try to load a XIB file that references one of the UI classes in the static library. This class exists in the XIB only and doesn’t have any outlets in the code file itself. (Even so, I manually added an outlet just in case to see if perhaps the class was getting optimized out.) However, no matter what I do, the XIB file will not load saying it can’t find the class.

    I’ve tried the -objC linker flag, I’ve tried every other thing I’ve found here in all of the comments, but nothing.

    On a side note, what I ended up doing was just adding (not copying, but adding a reference to) a folder containing all of the static library’s source files themselves (actually, at this point, it’s not technically a project anymore but just a ‘shared code’ folder with .h, .m and .mm files, plus a few resources in it and of course a main ‘someLib.h’ file that pulls in all the other headers), then just setting the target membership for the ones that I’m actually using in the product. That worked first time and also doesn’t create copies of the source files, plus it has the added benefit of not having extra code added to the main application from the static library that isn’t actually used by the application. My static library had an ‘a’ file of 450KB but the compiled app when doing it this way was only 87KB. That’s a huge savings. (Granted I don’t know how ‘bloated’ the .a files are, but that’s still significant if you ask me.)

    Another benefit is you just edit the ‘library’s’ files right in the one project. You don’t need a second instance of an Xcode window open. And finally, there’s only the build path of the executable itself.

    Of course this approach has one major downside of you manually having to select each and every file you *do* want to use while excluding those you don’t, but at least this ‘library’ only has about 30-40 files in it so it isn’t that bad. I do however see the appeal of Clint’s approach for much larger projects.

    Another tip, in the project tree, right-click on the headers and just choose ‘Target Membership’ You’ll get a nice list of checkboxes on the left that make it very easy to select what gets compiled and what doesn’t. It also lets you select target membership for the .a files so you don’t need to drag them to the target’s ‘linker’ phase. It’s automatically added there.

    But back to the original point. Anyone know why my XIB wouldn’t load the class from the static library in the first place?

  • http://www.bestfinance-blog.com Louise22PARKS

    Buildings are not very cheap and not everybody can buy it. Nevertheless, home loans are created to support people in such kind of situations.

  • http://xperienced.com.pl/blog/upgrading-cocos2d-version Upgrading cocos2d version | XPerienced Blog

    [...] Use XCode cross-project references and build static libraries on demand as described in a following post: http://www.clintharris.net/2009/iphone-app-shared-libraries/ [...]

  • Dennis

    I ran into the same thing as MarqueIV. I followed Clint’s directions for a previous external project and it worked fine. However, this time I am user Super Rewards SDK (which I believe has static objects) plugging it into my own project. When I compile I get this error:

    *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[UIViewController _loadViewFromNibNamed:bundle:] was unable to load a nib named “SROfferView”‘

    For some reason the project is looking to the Nib locally rather than the externally linked project. I added the Nibs to the local project and they worked – but ran into other issues.

  • Dennis

    FYI – problem was fixed similar to Marque’s. I had to add the nibs & any images in the project. I didn’t copy them over but merely linked them and it worked.

  • http://macgix.wordpress.com/2010/10/19/iphone-static-libraries/ iPhone Static Libraries « Macgix's Weblog

    [...] Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References — Cli…. [...]

  • http://appsinmypocket.com John

    Previously, I had my static library set-up in a different way that meant the library was not re-built automatically. I followed the clear steps in this blog and my static library does now get built automatically. I then hit another issue. I use a third-party library as is (just have the .a file, no source). Previously this always worked fine. To get the above to work though I had to leave the Library Search Paths blank, this meant the third-party library could no longer be found by the linker. Eventually I managed to overcome this by editing the “Other linker flags” option to include the full path for the file.

    One other tip would be to remember to select “All configurations” when you start making these changes.

    Many thanks for this blog. It still amazes me that something as basic as having your own library is so complicated in Xcode.

  • bob

    Unfortunately, I had everything setup and building, but for iPhone development there are problems with this approach.

    If you subclass any UIKit types and have them in a referenced project, interface builder will no longer see your subclasses of these types and you will not be able to for example set the files owner in IB to a subclass of UIViewController.

    Also, if you are using classes with rely on notifications, there are problems with those classes being invoked properly in the simulator if they are built in a static library. For example, if you package reachability (a common code found in iPhone apps) into a class which encapsulates its functionality and registration – it will not work from a static lib – I assume that means there are many others that wont work.

    So this is a nice approach and I tried it setup all my shared code in this way and it all built fine. but done expect your iphone app to run if you subclass UIKit types for common code and have them in a shared library. Or you use classes which register themselves for iPhone notifications.

    Im sure there are more problems. I think this really has to do with the funkyness of the build system for iPhone and probably would not affect Mac apps but I cant say for sure.

    Anyway, best approach if you want something to work every time, is to take your common code and put it into a template project (described on other blogs) and when a new project is created that code will be there. You can organize it however you want and you will not have build dependencies. If you change common code merge it back and merge the code from common shared as you need.

    This is incidentally actually a much safer way to share code since you cant really have dependent builds changing underneath you during development anyway.

  • http://appsinmypocket.com John

    I have lots of subclasses of UIKit in my library and it all works fine with IB. However, there is something you need to do in IB that maybe you’re not aware of. You need to get IB to read in the classes you want to use. Under the File menu choose the “Read class files” option. You need to select all the header files you want to use from your library. IB doesn’t seem to keep track of this very well, so sometimes you need to get them to read them in again.

    Hope this helps. This is a guess, but I’d check that you are referencing the header files you need for the notification to work.

  • Pierre

    Just a little word about path names… I am relatively new in XCode and Mac environments and i was struggling with trying to get static libraries working.

    After doing exactly what this tutorial was teaching, it still wasn’t working for me…

    After a couple of hours searching, i found out that:
    - the separator for multiple path names in User Header Search Path (and others) is whitespace
    - somewhere in the many directory names in my path name for the project of my static library, there was a whitespace!!!

    So the effect was that the compiler didn’t find the header files and couldn’t perform compiling at all. I had an error message stating that my class from my static library was not found…

    So, BEWARE of whitespaces !!!

    Is there any way of preventing this when using source trees variables ?

    Thanks and hope this will help someone…

  • http://web.mac.com/dbolli Derek Bolli

    @Pierre

    Putting “quotes” around the path in Xcode->Preferences->Source Trees works

    Also works for paths directly in Target->Build->User Search Paths etc.

    Regards,
    Derek.

  • http://labs.grupow.com/index.php/2010/12/objective-c-logging-with-sosmax/ Objective-C Logging with SOSmax at Labs

    [...] to the goal of keeping “common code” modular and atomic. ” for those people you can go here and here. [...]

  • http://questionlounge.com/why-are-static-library-headers-not-found/ Why are static library headers not found? – Question Lounge

    [...] I’ve used Clint Harris’ tutorial to set up code sharing between projects, and everything works just as expected on my computer. But [...]

  • http://www.tinkerbox.com.sg Jaryl Sim

    This has been working great for me when working with Cocos2D but when I try to use Box2D, I am running into a wall. Just including the header is problematic:

    #import “Box2D.h”

    This is the error that I am getting:

    error: Box2D/Common/b2Settings.h: No such file or directory

    In the static library, it is compiling fine.

  • http://www.logikstate.com Paul Carter

    You need to setup the header search paths of the main project.

    This is programming 101

  • http://www.tinkerbox.com.sg Jaryl Sim

    I already set the search paths up, otherwise Cocos2D will not compile so thanks for response but that is not the problem. If you have no experience working with what is asked in the question then do not answer.

    To get it to work, I had to check the ‘Always Search User Paths’ setting.

  • http://sinaptika.es/2011/01/enlaces-ios/ Enlaces iOS | Sináptika

    [...] Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References — Cli… [...]

  • https://spiderlogic.jira.com/wiki/display/SMP/iOS+development Confluence: SpiderLogic – Mobile Practice

    iOS development…

    General Domain Model Object Implementation Guide…

  • http://c5nn.carbonfive.com/2011/02/16/easy-modular-code-sharing-across-iphone-apps-static-libraries-and-cross-project-references-%e2%80%94-clintharris-net/ Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References — ClintHarris.net « Carbon Five News Network

    [...] Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References — Cli…. This entry was posted in Links. Bookmark the permalink. ← Vendoring Everything LikeBe the first to like this post. [...]

  • Terry Grossman

    Clint,
    Thanks for posting such a clear tutorial! Here are some notes that others may find useful:

    1. A previous comment by Bob (bob 11.05.10 at 4:40 am ) seemed to indicate there were issues with classes in a static library correctly receiving notifications. As far as I can tell from my own tests, this is no longer the case.

    2. I am using the iOS wireless distribution model to get LITE and PRO versions of my app to beta testers, and my typical workflow is to build both apps (in device/debug configuration) then upload them to a fileserver for others to get to. I found that modifying the name of the configurations in each project (to Debug LITE and Debug PRO, respectively) resulted in separate directories for the builds being placed into the shared build directory (instead of overwriting each other in a common DEBUG directory). So far there haven’t been any bad repercussions to doing this.

    3. I won’t bore you with the reasons why, but I needed some classes from the static library to get linked into my app, even when there was no explicit reference to the class. My first approach was to have the app delegate call a dummy method in the class which worked, but was a horrible hack. A better, more elegant solution I found is to define a blank category on the class. This forces the class to be included in the project, provides an easy mechanism to do so, and doesn’t involve introducing a dependency in the app delegate. sweet! :)

    Terry

  • http://ukiphoneappdevelopers.co.uk/2011/02/26/mobile-app-dvelopers-lis/ Mobile App Developers List « UK iPhone App Developers
  • http://productiseit.co.uk/2010/02/03/iphone-application-development-resources/ iPhone Application Development Resources « ProductiseIT
  • TheMisfit

    I’ve been using this technique for a while now and it works just great :-)
    However now that I switched to Xcode 4 I got confused with the new interface and settings.
    Any change on an update for the latest version of Xcode?

    Pretty please

  • http://web.mac.com/dbolli Derek Bolli

    @TheMisfit

    In Xcode 4 the steps are fairly similar

    Attach the linked Xcode Project file using Cmd-Opt-A to select

    Click on your Project (not the linked Project) in Project Navigator

    Click a Target->Build Phases->Target Dependencies
    Add libs as Target Dependencies

    Click a Target->Build Phases->Link Binary With Libraries
    Add libs as Linked Binaries

    My question is how to have a linked Xcode project in the new Xcode 4 templates?

    Regards,
    Derek.

  • TheMisfit

    Derek,

    Thanks, somehowe my target depency got deleted.
    It’s working now as before.

    Jan

  • http://www.learn-cocos2d.com Steffen Itterheim

    @Derek:
    I’ve been trying to figure this out myself. The Apple templates don’t even have a subfolder of files that is copied, much less a referenced project. I was able to figure out how to copy an entire folder without specifying each individual file (in Definitions use Path key and just use the folder name). But including a .xcodeproj file with corresponding files of that project? No luck. Most of the time Xcode gets confused and creates folder references which should actually be files.

    If I can figure it out, I’ll post it on my blog http://www.learn-cocos2d.com

  • http://www.learn-cocos2d.com Steffen Itterheim

    @Derek:
    To clarify the problem: all files that are specified in the TemplateInfo.plist file (Definitions) are added to the newly created project. You *can* specify an .xcodeproj file and that works, however the files referenced in this .xcodeproj will not be copied automatically, so the referenced project is missing all its files. If you do specify these files in the Definitions part, they get copied but they are added to the new project, which is not what you want and sometimes faulty (files regarded as folders).

    The Xcode 4 template format is missing one crucial process: copy some files/folders but don’t add them to the new project. If anyone finds out how to do that I’d appreciate a response (comment here is ok, I get notified).

  • a

    I also had tonnes of problems with the finer details regarding files containing only categories.

    1. -ObjC is case-sensitive. That correction will at least permit a compile.

    2. Add the following in case of further “unrecognized selector” exceptions. iPhone in particular,
    -all_load

    As outlined in the following doc.
    http://developer.apple.com/library/mac/#qa/qa1490/_index.html

    Otherwise, thanks for the tutorial.

  • http://creativestride.com/boston-web-design Web Design Boston

    Greetings! Thank you for your thoughtful post!

  • http://blog.kihongames.com/2011/labs-xcode-static-library-pitfalls/ Labs: XCode Static Library Pitfalls | Kihon Games

    [...] much, much has been written on the various processes available to get static libraries to function in XCode. [...]

  • http://programmersgoodies.com/in-xcode-4-how-create-a-multi-shared-project-setup In Xcode 4, how create a multi-shared project setup? – Programmers Goodies
  • Anonymous

    Hi friends,
    After including the library, when i try to call a method of that library , xcode gives me a waring ‘No such method found’ . But, the code gets compiled and even the method is called. Whats wrong ? need ur suggestions.