Macintosh Resources and Version Control

One of the most common (but becoming less common) problems with developing software for the Mactintosh is how to deal with the resources needed as part of any (pre-Mac OS X) Mac application. I've been working with them for a long time, and have never found an excellent solution, but here are a few of the solutions I've tried over the years, along with the good and bad points of each.

The first thing you need to consider is which version control system (VCS) you're using. Since most don't support binary files (or Macintosh resource forks), one choice is to simply work in the resource source language. A few mac-specific VCSes will allow you to check in compiled resource files, but few will offer you the ability to compare (or diff) them to find out what changed in which version. This means that you're stuck with having people lock the resource, make their changes, and then check it in. Only one person can be editing the resources at a time.

This suggests the first solution, which is to keep resources in files coupled to the source file which uses them. There are cases where this isn't practical (such as an application-wide list of error messages), but simply breaking things apart into a number of smaller resource files can solve a lot of problems. But having many small files means that the odds of two developers needing to edit the same file at the same time are much lower than if all the resources are collected in a single file.

If you're using a VCS which doesn't support checking in binary files, you'll need to save your resources in their source or de-compiled form. The standard format for this is Rez format, named after the MPW tool which compiles resource source into binary resources. The major problem with this format is that most resources are more easily edited by a visual resource editor, such as Resorcerer, ResEdit, Constructor or Project Builder. After editing the resources visually, you'll then need to DeRez the resources in order to get a plain-text source file. The problem is that the decompiled resources will often not be in the same order they were before compiling, which means that comparing the soruce files in order to do a merge will show huge differences, as the resources have been shuffled around in the file.

We're back to maintaining everything in source, and some folks actually choose to do their editing directly in the source. While this makes it trivial to do text-file comparisons, editing the resource files is more time consuming. It's like the difference between editing raw HTML and using a WYSIWYG editor only worse, since the developer not only needs to keep the various resource type definitions in mind, but also will usually end up needing to iterate multiple times in order to get the desired visual layout.

This suggests the first solution again. By breaking the resources into smaller chunks, you have fewer resources per file, which means that you don't have to worry as much about the resources changing order in the decompiled source.

One other problem with decompiling resources that have been edited with a visual editor is that it's more difficult to keep around symbolic names for values. When you derez the resources, you'll get numbers like -39, rather than a symbolic constant like EOF_ERROR or kEofErr. Or if you do craft a header file with all your constants in it, you may end up getting symbolic constants where they're not appropriate (because DeRez can't tell the difference between the 23 different meanings you have for the number 80), which can be worse (because it's misleading) than having no constants at all (where it's obvious you have to go look up the constants). You also lose the ability to have computed constants, such as (kWindowLeftEdge + 23), since they get collapsed to a single integer.

Again, breaking your resources into smaller chunks will help.

A final problem with saving the resources as decompiled text is that editing resources using some tools on some versions of Mac OS will put the resources back into the file in most-recently-edited-last order. That is, the most recent resource to have been edited ends up being the last resource in the file.

The answer to this seems to be sorting the resources. You could do it with a tool that operates on the compiled resources if one existed, but then you're still dependent on the tool that does the decompiling. The best bet is probably to sort the resource-source after it's been decompiled. I'm working on a script to do that and hope to make it available here soon.

Copyright 2009, Dave Polaschek. Last updated on Mon, 15 Feb 2010 14:09:34.