Skip to content

Instantly share code, notes, and snippets.

@nkpart
Created September 16, 2010 10:32
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nkpart/582228 to your computer and use it in GitHub Desktop.
Save nkpart/582228 to your computer and use it in GitHub Desktop.
Kit - package manager for Objective-C

Packages. Boy, I just don't know.

I'd like to introduce a tool I've written, that I hope will make it easier to share objective-C code across iPhone projects.

The tool is Kit. To install it, you'll need the latest haskell platform release for OS X. Kit installs through haskell's package manager:

$ brew install haskell-platform # If you've got brew, otherwise: http://hackage.haskell.org/platform/mac.html
$ cabal update
$ cabal install kit
$ kit --version # this is how you know it's working. If it's not yet working, maybe ~/.cabal/bin 
                # isn't on your path

Kit combines source-only Objective-C projects into a one super dependency that you use in your project. By source-based, I mean a project that is composed solely of Objective-C code - no static libs. Kit is still in its infancy, and a lot of nice things like that are missing.

Making a Kit

These source-only projects are called kits. Imagine you had some classes for doing logging. Maybe it has all sorts of cool shit like levels, source-file information, current thread IDs, etc. Call it logface. Whatever. You lay out your project directory like this:

KitSpec -- we'll get to this soon
src/ -- all your source goes here. Headers and implementation. 
        This directory is placed in the HEADER_SEARCH_PATH for 
        projects that consume this kit.
test/ -- they're included but not used
logface.xcconfig -- any special compilation flags that your library needs

Great, now that we've obeyed kit's stringent demands for project layout, we create a KitSpec which tells kit the name, version number, and dependencies of your project:

{
    "name" : "logface",
    "version" : "0.1",
    "dependencies" : []
}

It looks like JSON, because it is. A quick word about versions. Kit is dumb. It does no version conflict checking, or resolution of suitable versions that satisfy all dependencies. If you depend on 2 different versions of a project, directly or indirectly, things will blow up.

Sharing a Kit

'logface' is looking pretty good now. So lets make it usable by our other projects. When kit looks for dependencies, right now it looks in one local repository: ~/.kit/repository. Kit knows how to stick stuff in it, and pull stuff out of it:

$ cd log-face
$ kit publish-local
$ ll ~/.kit/repository/logface/0.1 # This is where it got published to.

Using a kit

Now we kick off with our main business: making a guaranteed top 10 app - Angry Fruit Ninja III, and it needs a logging library. First, we make our app a kit by giving it a KitSpec. We're not going to publish this one though, we're using the kitspec to declare a dependency on logface.

$ cd angry-fruit-ninja-iii
$ cat KitSpec 
{ 
    "name" : "angry-fruit-ninja-iii",
    "version" : "0.9",
    "dependencies" : [
        { "name" : "logface", "version" : "0.1" }
    ]
}

Now the money shot:

$ kit update
Dependencies: logface-0.1
-> Installing logface-0.1
-> Generating XCode project...
Kit complete. You may need to restart Xcode for it to pick up any changes.

$ # Note existence of 'Kits' directory.

Kit has generated a project file that includes all the source from all your dependencies. The project is sitting in Kits/KitDeps.xcodeproj. The kits your project depended on have been pulled out of your local kit repository (~/.kit/repository).

To use the kits, modify Angry Fruit Ninja's Xcode project like so:

  1. Add Kits/KitDeps.xcodeproj and Kits/Kit.xcconfig as items in your project. Group them up in a group named 'Kits' if you like.
  2. All build configurations need to be base on Kits/Kit.xcconfig. If you use other xcconfig files, make sure they #include "Kits/Kit.xcconfig" at some point.
  3. The app target should depend on KitDeps.xcodeproj. This means that Xcode will compile KitDeps before it compiles your project.
  4. The app should link against libKitDeps.a, from KitDeps.xcodeproj.

Phew. And that's it.

Next Steps and Random Tips

Kit's pretty spartan on features. So there are a few things you might like to know about how I (and my fellow devs at mogeneration) use it.

  1. We have a lot of company IP built up in kits, so we can't publish our kit repository publicly. We keep all our kits in a private git repository that everyone clones into ~/.kit. Works a charm.
  2. When we use external code, we create a fork on github. Then we massage the project into the structure kit likes and pop in a KitSpec. Then it's a matter of running publish-local, committing and pushing our private kit repo in ~/.kit (git managed, if you recall), then let everyone know to update their copies.
  3. kit verify is pretty cool. It tries to use the current kit as a dependency in an empty shell project. This will tell you if all your dependencies can be compiled together.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment