Thursday, February 25, 2010
SVN: externals - Key to sharing libraries
As any developer knows, it’s very useful to reuse code. If you have written some code that performs a useful function, it makes sense to modularize it so it can be easily reused in other projects.
If all your development is occurring on one machine, then sharing those modules between projects can be fairly simple. In my case, I have a custom Libs/ directory where I put common source code for various features, such as my web view controller, my RadioKit audio streaming engine, autoscroll label, etc. When I want to use any of those modules in a new project, I directly reference this common Libs/ directory. That way, if I later fix a bug in a module, I don’t have to find everywhere I’ve included the code. All the projects reference the same source and the change is easily reflected across all my projects.
Now, add in the complexity that you don’t have all the modules in a common directory on one computer. How can you still easily share the code across projects and ensure they automatically include new changes when they are made? SVN!
SVN (or Subversion) is a source code version control system. There are plenty of alternatives to SVN, and they all have their merits, but since SVN comes with the Mac, it’s an easy option to use.
I’m not going to get into the details of setting up SVN to use with XCode. That’s been covered well in other places. What I do want to talk about is a handy feature of SVN which makes sharing pieces of other SVN projects in a single project. The feature is called “externals”.
Suppose you have an iPhone XCode project that is being managed via SVN. Now, suppose you want this project to include 2 additional modules, and the source code for each module is hosted on a different SVN repository. You could manually check-out each of the pieces which will make up the project, but now suppose someone else wants to also work on this project. You would need to tell them where to get the extra modules and they would have to manually fetch (or check-out) the code from the other two repositories and put it in the proper place.
With SVN externals, you avoid all that manual work. You can easily define in your project where all the external pieces are coming from. These externals definitions get saved as part of your SVN project, so if someone else checks out the same project, SVN will also automatically check out the necessary pieces that were hosted on the other external SVN repositories. And, when you then open the project in XCode, XCode will automatically track the changes to the whole project, even the modules that were retrieved from the external repositories.
The externals feature makes it a whole lot easier to manage pieces from multiple SVN repositories, all while making them appear to be self-contained in the current project.
There’s a decent description of the syntax for using “externals” here. Also, most graphical SVN tools (such as Cornerstone or Versions) have support for defining externals. Unfortunately, the XCode SVN interface does not provide a method for defining externals. You need to either use the command-line or a GUI tool to initially set them up.
NOTE: since the externals are a property of a project, in order to define them you must first check-out the project which will use them. I didn’t understand this detail at first and spent quite a bit of time trying to figure out why the externals option was read-only when using the GUI tools and looking at the repository. If you run into that problem, check-out the project first, and then set the externals property on the working directory, not the repository.