As I’ve blogged before, I’ve spent a fair amount of my spare time recently getting to know OS X development, and one thing I’ve wanted to do is get an automated SDK build going for before the next release goes out. Annoyances with the organisation of framework versions, and issues with driving PackageManager from the command line have all frustrated those efforts, but nevertheless I’ve made progress. Today, however, despite having a mostly working installer I decided to change tack completely and drop PackageManager in favour of a disk image (dmg) instead:
The reasons for deciding to do this are numerous. Firstly, the issues with framework versioning in a build environment have basically meant that the only way to do this reliably is to contain everything in a single folder anyway, so that all the references are local, rather than using multiple framework versions in one central location. This means that PackageManager’s ability to install different things in different locations (central and per-user) became useless. Having a global framework system just doesn’t work for development when version selection is non-existent. Secondly, for some incredibly bizarre reason PackageManager is totally incapable of defaulting the install location to anywhere derived from the users home directory - the only way to do it is to install somewhere else and copy, which is messy, especially if you want the user to have a choice of install location, which I do. Finally, and perhaps most importantly, I’ve experienced more app distributions now and now realise that installers aren’t en vogue in OS X like they are in Windows - DMGs rule (here’s a selection - yeah I know mine isn’t as pretty but I don’t have that much time :)).
For those who don’t know, DMGs are just ‘pretend’ disks / volumes. They can be read / write or read-only and can be compressed and encrypted if you want. OS X uses them as containers for burning DVDs and distributing software among other things, they’re very flexible. As a software distribution mechanism, they gel with the OS X ‘drag and drop install’ idiom whilst at the same time being more elegant than a simple .tar.bz2 archive. So generally, they’re a good thing.
Creating the ‘look’ is as simple as creating a base disk image using Disk Utility (or the command line version ‘hdiutil’, more on that in a sec), mounting it and playing with the appearance in Finder (just make sure the view opions are set to just this folder). Any changes you make are preserved in the image next time you mount it. This becomes your ‘template’ DMG that you can populate with content with the SDK script.
To mount, update and finally write and compress a DMG from the command line is pretty easy. To start with, we have to mount the template image we created by hand (you probably want to bzip2 this image for storage in source control):
cp template.dmg workingcopy.dmg
hdiutil attach workingcopy.dmg -noautoopen -quiet -mountpoint tmp_dmg
Copy whatever you want into the mounted location tmp_dmg, then you’re ready to finish up. Firstly, you want to make sure that when the user double-clicks on the dmg that it not only mounts, but automatically opens that nice folder you designed. The ‘bless’ command does this:
bless -folder tmp_dmg -openfolder tmp_dmg
Finally, you want to unmount the image and compress it.
hdiutil detach tmpdmg
hdiutil convert -format UDBZ -o OgreSDK$OGRE_VERSION.dmg workingcopy.dmg
rm -rf tmp_dmg
That’s it! The -format UDBZ tells hdiutil to BZip the image so it’s nice and compact, ready for uploading. Seems to work pretty well. I have a few loose ends to tidy up like writing a new ReadMe but otherwise I think I’m done, so should be able to release the next version in a few days.