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

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


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


I'm using https://github.com/jverkoey/iOS-Framework to achieve something quite similar to your needs. Give him all the credit, I'm just summarizing how I do it.

Create a static library as usual plus these tweaks:

  • Add a copy files phase to copy the headers. I don't use a proper "Copy headers" phase because I read somewhere it's not recommended for iOS static libraries.
    • Destination: Products Directory
    • Subpath: ${PROJECT_NAME}/Headers
  • Change a few settings:
    • "Dead Code Stripping" => No (for all settings)
    • "Strip Debug Symbols During Copy" => No (for all settings)
    • "Strip Style" => Non-Global Symbols (for all settings)
  • Add a run script to prepare a framework with the library:
    • Use the script prepare_framework.sh.

You can use the static library project in your app: drag it to your app project, add the .a library as dependency and link with it. You can debug the library along with your app, step into methods, navigate to symbol definitions, etc.

The prepared framework will be used to distribute a binary version:

In the same static library project add an Aggregate target:

  • Add the static library as dependency.
  • Add a run script phase to build the missing architectures. Use the script build_framework.sh.

The script guess what's the other platform and use xcodebuild to compile it. Then use lipo to create a fat binary with all the architectures. The destination of the fat static library will be the framework tree we created before. The final framework is copied to the products folder in the build folder.

With this approach you can:

  • Build and debug your app with the static library as nested project.
  • Build a distributable version of the library in one step with the headers embedded in a framework-like bundle. The built framework is located in the project Products directory.
  • Use Xcode Archive function. For some reason final files are not copied to the archive location. You can use it to build a stripped version of the framework.

Feel free to clone a project using this technique to package the library: json-framework fork. I have modified slightly the scripts, check my fork of iOS-framework.

Regarding armv6, I guess you need and old iOS SDK 4.3 and add manually the literal armv6 to the list of valid architectures and actual architectures. I don't have and old SDK to test it right now.


Cocoapods covers your needs. Although the standard way to use it is to submit pod specs to a central git repo. It supports adding alternate repos for distribution, or manually creating them, see here. The advantages of using cocoapods would be that it both meets all your requirements and that it is becoming a very standard way of distributing libraries (e.g. used by companies such as facebook & stackmob) and open source (e.g. afnetworking). So, if you depend on 3rd party libraries now or in the future, chances are that cocoapods will help you handle that dependency.