Search code examples
iosxcode4xcode4.5xcodebuild

Xcode with iOS - Creating a library in a way that is easy to run in debug mode, distribute, iterate


This is for Xcode 4.5.x iOS armv7 armv7s and the sim and specifcially about Xcode project setup / project build setup:

I have a project "A" that is an app in the app store. I have a project "B" that is a library that will be used in A as a dependency, but also distributed as a 3rd-party library to other companies to use in their apps. (other companies' 3rd party apps are represented in this case as "Y").

Here are the requirements:

  • Must be able to run "A" in debug mode, and of course debug the nested "B" project concurrently, in the same build/session.
  • From "A" I can CMD+Click on a method signature from "B" and jump right into that src file, where I'm free to edit and then recompile, as if it were from the same project.
  • A dev "X" at some other company must be able to easily drag our library "B" into his project "Y", where "B" is a static library with only the required header files exposed. "Y" of course calls methods from a subset of "B"'s actual header files. Only the files from this subset should be included in distribution for Dev "X".
  • Dev "X" should not need to modify anything at all in his Xcode project, just drag the folder for "B" (which contains the static lib and subset of header files) into his project and click "Copy resources, create references, etc".
  • I need to be able to generate the static library build of "B" easily, based on the same files I have been editing this whole time as I iterate and debug this project "B" inside of its dependent project "A".
  • "B" has no resources aside from source code -- there are no image assets, xibs, or anything like that.
  • From "B", I click "Archive" and Poof! there's a static lib (must be fat binary, by that I mean it works on the simulator + armv7 + armv7s, please!!) with the essential header files ready to be distributed.
  • All of this must be app store approval-friendly
  • Also this must be reliable. It's no good if I have to keep coming back to make a lot of config changes every time I add one file.

UPDATE:
* MOST IMPORTANT: This needs to be a repo I can check out that is a full end-to-end template of what am looking for, and I need to be able to open up Xcode 4.5.2+ and click play and see this thing build, pain-free.

500 points to anyone who can provide me a template project that demonstrates everything I have described above, "A", "B", and "Y" (with "B" static lib used as a dep). All i need is a set of skeleton projects ("A", "B" (nested inside "A"), and "Y") that shows how this can be done. Please don't hold back the answer until the bounty is posted. If it meets my requirements, I'll make sure you get my bounty points.

I'm somewhat worried that with the limitations of Xcode that this is not even possible in a way that is not a complete hassle. Please prove me wrong.

UPDATE: I decided I don't care about armv6 anymore. Goodbye, armv6. Extra credit if you can get armv6 rolled into the dist output along with armv7, armv7s, i386/simulator.

P.S. I promise that I will be reasonable awarding the points. I'm not looking to withhold them on a technicality. If you make my life dramatically less painful in this one area, I will gladly award you the points.


Solution

  • This will not be possible in Xcode alone. You will need some build Scripts (which you can call from within Xcode of course) because of the compilation target switch (simulator, device, etc.).

    I think you will have to add additional distribution headers to a "Copy files" build step at least. But other modifications should not be necessary if you change something.

    I did something like this for libturbojpeg, see https://github.com/dunkelstern/libturbojpeg-ios for reference. It currently puts a fat library into "lib" if you call the "build.sh" file from the terminal, but omits distribution headers. In the case of libturbojpeg I needed 2 project files because each target compiles a different subset of assembler files into the library (better do not look at the assembler makefile stuff). To compile you will need a recent version of NASM as the version apple ships is ancient (get it with brew). I will post a template for such a library build project on the same account shortly. (Will edit or comment if done here with appropriate links)

    Basically it works like this:

    1. Create a build script that calls xcodebuild for each needed platform target
    2. The Xcode library project has to contain a script to drop the built libraries in a directory the build script can find
    3. Additional headers have to be copied by a "Copy files" target action
    4. The build script has to merge all library builds with lipo
    5. Add the build script as "Run Script" target to your build, but be aware you do not create an infinite loop (or just call it from terminal for creating a release build)
    6. In your main project add the library subproject

    You can then distribute the output dir with the copied header files and the lipo merged universal library and use the library normally as subproject in your workspace as you would do normally (it builds and links only the needed libs then, not the universal lib but that should be no problem)

    This does not in fact solve the problem of creating DSYM files for the library. But normally the debugging symbols should be in the library itself when building a debug build. It will strip the debugging symbols on release build and you will have no DSYM then.

    Link to example project: https://github.com/dunkelstern/StaticLibraryTemplate