Showing posts with label tools. Show all posts
Showing posts with label tools. Show all posts

Saturday, 25 February 2012

Xcode 4 C++ class template updated

I've updated the C++ class template for Xcode 4. You may want to take the latest from github and re-run your installation scripts.

This version now:

  • Allows you to specify a class' (optional) superclass
  • Allows you to add a virtual destructor
  • Can make a new class non-copyable (with hidden copy constructor and assignment operator)
  • Has a sexy icon that matches all the other Xcode template icons.


Could life get any better?

Grab the update from Github here.

Thursday, 23 February 2012

Xcode 4: A C++ class template

Xcode 4 C++ users, rejoice!

It's really annoying that Xcode 4 has never shipped with a template for creating a new C++ class, with header and implementation file.

It lets you create objective C classes with header and implementation. But you always have to create a C++ header file in one step, and then the implementation in a second step.

And, honestly, why do those steps take so long to update the project?

It's not good enough, and so here's the answer...

The Xcode 4 C++ Class Template

I've created a super-simple to install C++ class template and installer.

Grab it on Github here.

Using it is a simple case of running a script and restarting Xcode. I've built in support for Xcode 4.2 and the new Xcode 4.3. The installer runs a number of sanity checks to make sure you're not about to install something dumb on your computer.

Full docs are in the README file up there.

I hope you find it useful. I know I do.

Making your life better, one class at a time...

Thursday, 5 January 2012

Installing Groove Agent 3 (Update from Version 1) on Mac OS Lion

It all seemed so simple. I wanted to install my trusty copy of Groove Agent 3 on a new Mac OS Lion box. The license is on my eLicenser already. So it should just be a quick insert-DVD-and-install job.

Shouldn't it?

Of course not.


#Fail...

I've been using Groove Agent for years now. My version 3 DVD was an upgrade disk from the original version 1. If you run that DVD's installer it says you have to have version 1 installed to upgrade. That seems fair enough.

Except you can't install Version 1 on Lion; it is an old PPC application, and Lion doesn't support Rosetta any more.

It's a deadly circle; I now legitimately own some (not inexpensive) software that I can't install. Pete is not a happy bunny.


Attempt 1: tech support

I sent a tech support email through my Steinberg account. Not with much hope, I have to admit.

That was ages ago. What do you think happened?

Yup, you're right. Not even got a "we've got your message and it's in a queue" reply.

Thanks, Steinberg. Thanks a bunch.

But where there's a will, there's a way...


Attempt 2: Check for updates on the website

The Groove Agent 3 support site has a few update installers available (which, naturally, need the full program installed first to be able to update).

There is also a new "full installer" for the Mac to replace the DVD's installer for first-time users. This shows great promise.

Once downloaded, I run the installer. "Insert the Content DVD" it asks (impolitely). OK, again this is fair enough. The content is enormous, and is on the DVD already so I shouldn't need to download that again. It also proves that I own the product I'm installing.

I insert my Groove Agent 3 DVD into the machine. The installer doesn't recognise it. No message. No hint. No continue button. It just sits there.

Of course, it's looking for the "Groove Agent Installation DVD" not the "Groove Agent Update Installation DVD". Swines.

Absolute swines.

But where there's a will, there's a way...


Attempt 3: Trick the installer

Being a techie I wonder. I wonder how rubbish they really are... Is the installer just looking for a DVD called a certain name?
ln -s "/Volumes/Groove Agent Update DVD"  "/Volumes/Groove Agent DVD"
Run the installer again.

Success!!!

The installer runs, it copies over the content from the DVD and there's my Groove Agent 3 sitting there, ready to run.

Goodliffe: 1, Steinberg: 0, (Steinberg Customer Support: -5)


But, we're not there quite yet

I fire up Cubase, pull in the virtual instrument, and a window pops up asking me to locate the content files. That's the content that the installer just installed. Into a standard place. Didn't it think to look there itself? Sheesh.

That's OK, I'll just use the file browser dialogue that appears to load it. Except that the content is automatically installed into "/Library/Application Support/Steinberg/Groove Agent".

Notice that first bit. Yes, "/Library". The folder that Apple now HIDES from users in Lion so they can't fry in innards of their OS. I physically can't navigate to the content. Genius.

The trick, of course, is to launch Finder, open the "Go" menu, and hold down the Command key. At this point "Library" magically appears in the middle of the menu's list of places you can go to. Select that folder. Navigate to the right directory in the Finder window that appears, and then drag the target directory into the patiently waiting application's file open dialogue.

What a palaver.

But that's it, I now definitely have Groove Agent 3 installed and running.


Whinge

Of course, I have a clue what's going on inside my computer, and was able to engineer this solution based on my experience and a selection of educated guesses. Goodness only knows what the average user would be able to make of this situation.

(Hopefully this blog post will help someone in time. Let me know if it does!)


Endnote

It seems that every time I want to sit down an use my computer to make music, the computer wants some love, wants its nappy changed, or wants feeding first.

 New driver required! Update available! Incompatibility detected!

Technology really can get in the way of being creative.

Monday, 5 December 2011

Skip Lists: A C++ STL-style implementation

Recently someone mentioned an interesting container type to me, the skip list. It piqued my interest and so, naturally, I wanted to play around with it. It's been a while since I last wrote an STL-style container, so I thought I'd attempt to write an STL-compatible skip list implementation. Fun times.

And so I present to you my latest code offering, the C++ STL-style skip_list container. Grab it from the GitHub project here. Or read on for further information...


Skipping the list

The skip list is an interesting data structure. You could (simplistically) consider it a hybrid of a std::list and a std::set; it's a list-like data structure than provides good insertion, removal and search performance. As ever, the trick to good search speed is to trade off some memory to improve traversal performance.

Traditionally the skip list is an extension of a standard forwards-only linked list. Wikipedia has a pretty good page on the structure. Check it out if you want more gory details.

Atop a standard linked it, it maintains a set of higher-order linked lists that act as indexes into the main structure below. These provide faster access to the middle of the list. This provides efficiency on a par with a balanced binary tree (i.e. what a std::set is usually implemented in terms of). Insertion, removal and search operations are typically O(log N). Remember: a standard linked list (which you'd have to manually keep in order) would have all those operations take O(N).

The particularly interesting detail about the skip list implementation is the algorithm used to determine the allocation of nodes to higher-order lists. Rather than use a fixed balancing scheme, or inspecting the data as it's added and comparing against the existing structure, we assign nodes to levels probabilistically - always adding them to the main list, and then (with decreasing levels of probability) adding them to the high levels lists, too.


My implementation

I chose to implement a bi-directional skip list, so each node in my version retains a back-pointer to the previous node. This makes the list more useful in general, and ensures that it's a drop-in replacement for std::list.

Like std::set, my version takes a template Comparison functor (typically std::less) so you can tailor the ordering of data in your container. I also, naturally, support custom allocators, and provide all "the usual" STL container operations.

I have tested the code on:
  • Mac OS using Xcode 4.2
  • Windows usigin Visual Studio 2008
  • Linux using gcc 4.4
I have benchmarked the performance of my skip_list container. Because of the probabilistic nature of the container, sometimes it will perform better than other times when given random test data.

The memory consumption is almost exactly the same as std::set in general, and it tends to allow faster forwards and reverse iteration. Depending on the way the wind is blowing, large node insertion/removal operations can be dramatically faster (taking a little as 25% of the time of std::set for the same data) or a bit slower (I've seen up to ~110%).

The source archive contains my benchmarking code, so feel free to try it yourself.

The GitHub project for skip_list is https://github.com/petegoodliffe/skip_list.


Future plans

I have not yet provided C++11 "move" or initialiser_list operations, so that would be an interesting addition.

I could extend the data structure to provide O(log N) random access (e.g. indexing and random access iteration), too, at the expense of one more integer value in each node. That would be an interesting extension to consider - probably as a parallel variant of the existing container.


Future writings

If there's enough interest, I might start a new blog series on writing an STL-like container based on this implementation. There was a lot of interest in my previous series describing an STL-style circular buffer. Since this is a meatier data structure, the case study would be more useful.

Let me know if you'd like this!

Wednesday, 16 November 2011

Xcode 4 keyboard/mouse shortcuts

(I'm posting this here mostly so I don't lose it, although I'm sure it'll be useful to other Xcode 4 users out there.)

There are a couple of really handy Xcode mouse click modifier key combinations that I can never remember when I want them (kind of like a Super Street Fighter key combo).

In particular, you can click on symbols in the code editor and have them open in this editor, in the alt editor, in a new window, or... even... with a (ugly looking) popup asking you where to open (e.g. in a new tab).

Here's the lowdown:


Xcode 4 editor symbol clicks

Modifiers Click What happens
⌘⎇^ + single Open in alt editor
⌘⎇⇧ + single Select where to open (with popup)

+ single Open in this editor
+ double Open in this new editor window
+ single Show help popup
+ double Show help in organiser

⌘⎇⇧ Make alt editor counterpart again (super useful)

Key (what the silly symbols mean) 
Command (cmd)
Option (alt)
^ Control (ctrl)
Shift

Wednesday, 21 September 2011

iOS: Using older SDKs with newer Xcode versions

When you update Xcode versions, the installer automatically removes any old SDKs you have lying around, and replaces them with the latest version.

This is fine behaviour, as the most recent SDKs remain backwards compatible. You can set your project to target older iOS versions. If you do this, the newer SDK features are disabled for you.

However, there are times when you need to use an older SDK.

For example, I am running the latest Xcode with a beta iOS 5 SDK installed. Since this was originally installed on a clean machine, I didn't set the beta install to use a parallel directory and leave the "release version" of the developer tools intact - they simply weren't installed. (Making a parallel install is, in general, the best practice when installing a beta Xcode/SDK set).

Fear not. You can still get your newer Xcode to build with an older SDK, without downgrading your Xcode or making a parallel install:


  • Close any running Xcode instance you have open.
  • Locate the install DMG for an old version of Xcode (e.g. Xcode_3.2.5_and_ios_sdk_4.2_final.dmg, they name them so well) and open it.
  • Do not run the installer!
  • Open the Packages directory in that disk image. It is a hidden directory. Try this terminal incantation: "open /Volumes/Xcode\ and\ iOS\ SDK/Packages"
  • Locate the iPhoneOS and iPhoneSimulator SDKs for the version you want. Run just those pkg files. (e.g. I ran the iPhoneSDK4_2.pkg and it's matching iPhoneSimulatorSDK4_2.pkg)
  • Make sure you specify the /Developer directory as your install location. If you don't, the SDKs will be installed in your root directory, under the /Platforms directory; you'll have to manually copy them into /Developer/Platforms yourself.
  • Now, re-open Xcode. If the SDKs installed in the right locations, they will be selectable in your project now.


Tuesday, 20 September 2011

How to set up Jenkins CI on a Mac

In this post I will describe how to get a running Jenkins server set up on your Mac. Like most free software ("free" as in price and "free" as in freedom), Jenkins is very capable, very functional, and mostly documented. But it didn't quite work out of the box.

As with many such projects, you get far more than you pay for. But you can end up spending more than you expect.

There aren't enough step-by-step how-to guides. And there aren't many documents that help you out when things go wrong. There is a great community behind Jenkins, though, which does help. And plenty of people moaning and blogging. Now I'm adding to that noise.

It took me a few days to get the setup working properly. Hopefully this story-cum-howto will save you some of that effort.

The Prologue

All good developers know that a continuous integration (CI) server is a linchpin of the development effort. I joined a large software project without one, and made loud noises that we needed one. And so, it naturally fell to me to set up.

It's been some time since I set up a CI server. Previously, I've used ViewTier's Parabuild. It was more than adequate. But times have moved on. Although I still have a licence for it, the cools kids are hanging around at other parties these days.

Jenkins (the recent fork of Husdon) seems well-regarded, popular, and to have a good development and support community. It's also open source, so seemed the right way to go. Plenty of people have sung it's praises to me in the past, and that kind of thing counts for a lost.

Our requirements for the builds were:
  • to build two products from the same codebase on Mac OSX
  • to build two products from the same codebase on Windows

Both of these need 32-bit and 64-bit versions.

That's already a reasonable configuration matrix, and highlighted why we needed CI in place. A developer would check in a tweak that they'd built on one configuration. All the other config could easily get broken without anyone noticing for a while.

So: Jenkins to the rescue.

Almost.

I purchased a small Mac Mini to use as a build server. I downloaded a copy of Jenkins (free, whoop!), installed the Mac dev tools (free, whoop!) bought (and installed) Parallels, Windows 7, and the Visual Studio toolchain (not quite as free), and sat down for a small configuration session.


Getting your project ready for a CI build

Before setting up your build on an CI server, you should first create a simple script that builds everything from a clean checkout. Then check that script into the repository, to be versioned alongside the software itself.

For our project, I already had that in place. The script cleaned, built, versioned and packaged the software in one step.

Such scripts are clearly useful for deployment on a CI server, and also for making official software releases by hand, whether or not you release from the CI server builds. It's a record of the recipe needed to build a release.

With a fixed recipe like this in place, every software release can be guaranteed to be good and reproducible.

That's development 101.




Installing Jenkins on the Mac

The Jenkins website has a handy Mac installer that you can download. (In retrospect, I'm not sure if this was more hassle than it was worth, but this is the route I obviously sought to go down.)

STEP 1: Install Jenkins

Download the Mac installer and run it.

This installer creates a system launch daemon that fires up Jenkins when your machine boots. This runs in the background even if you haven't logged in, making a true stand-alone build server installation.

However, if you have a fresh Lion install you don't yet have Java.

STEP 2: Install Java

Try to run a Java app. Any app. The OS may fumble around for a while looking for Java. If you're lucky, it'll download and install it automatically. Otherwise, install it by hand.

And of course, now, Jenkins "just works".

Not.


Configuring Jenkins on the Mac

The Jenkins war (web application archive) is unpacked into /Users/shared/Jenkins. The application runs from there. All configuration is stored there. The source code checkouts and builds go in there. It's the center of your Jenkins universe.

A launch daemon plist is installed in /Library/LaunchDaemons. It runs a script /Library/Application Support/jenkins-runner.sh as the user "daemon" (a system specific user that runs background processes - it is not shown on the login screen, nor does it have a home directory).

This installation has all the hallmarks of a runnable system. You can now point your browser to http://localhost:8080 and start configuring the Jenkins server. The lights are most definitely on. But no one's home yet. As we're about to see...

STEP 3: Set up Jenkins to build a Mac project

I was a good soldier with a simple shell script that built and packaged my application. If you don't have this, write one now. To build Mac projects, you'll need some cunning invocation of xcodebuild and probably packagemaker.

This single script is a critical step in configuring your build job. Whilst it is possible to place multiple build commands into the Jenkins task itself, it's far better to keep them under source control in a script checked in to your codebase (if you need to ask why then you probably need to go to a more basic tutorial!).

Configure Jenkins to check out your repository, to react to appropriate build triggers (e.g. manual build requests through the UI, automatic detection of the repository changing, or other triggers) and to run the appropriate scripts to kick off the build.

Then press "Build Now" to start your first build.

In all probability Jenkins will crash and burn. But don't tear your hair out just yet. You'll be needing it for later on.


Fix Jenkins so it works

Welcome to the nether-world of almost working builds.

STEP 4: Configure the Java heap size

My project is large. It includes lots of third party libraries, including the vastness that is Boost and many other comparable-size libraries. There are also several SDKs that are shipped as large binaries (with versions for each platform and 32/64 bit). That's a lot of data to shovel around.

Jenkins choked trying to check out this monster. It would collapse with Java heap exhaustion errors before it even got to triggering a build. Goodness only knows why a large heap is required to check files out of a subversion repository, but the solution can only be to increase the heap size to remove the bottleneck.

By default, Java allocates a very conservative default heap size to running applications; I believe its 256M or  so on 32-bit Mac OS.

On the Mac, this can be changed using the "Java Preferences" application (found in the /Applications/Utilities folder). The trick is to adjust the Java launch command line (hit Options...) to include the comand-line sneeze: "-Xmx1024M" (or whatever heap size you want). However, this didn't seem to affect the Jenkins Java process launched through launchd.

To set the heap size in that context, you have to adjust the launch script itself. You can place the command line switch into the jenkins-runner.sh file directly. However, the file does have provision to load the heap size parameter from a configuration plist. This plist does not exist by default, but you can create/edit it with the following incantation:

sudo defaults write /Library/Preferences/org.jenkins-ci heapSize 1024M

This will write a file /Library/Preferences/org.jenkins-ci.plist (note that you must not specify the plist file extension to the defaults command).

To make the system use this new heap size, you can't just restart Jenkins (either gracefully within the web interface, or by "kill -9"-ing the process. You can't even use "sudo launchctl {stop,start} org.jenkins-ci".

You could reboot. Or, more cleanly, you have to force launchd to reload of the configuration for the launch daemon using launchctl by unloading, and then reloading the daemon. It's the reloading that'll force the new configuration to take hold. (It took me a while to figure that one out!)

With an increased heap, Jenkins will fall over less. In my case, I got through a whole checkout.

But once Jenkins manages to check out the project and run the build script, you're still not quite done...

My script called xcodebuild to invoke Xcode from the command line to build the various configurations of the project. This script worked fine when run directly from the command line. However, when running within Jenkins it would bomb out with quite unfathomable errors - e.g. NSAssertions triggered from deep within the Xcode IDE codebase. Or it would just enter a hibernation state; lock-up completely, performing no work, but generating no error.

The reason for the strangeness is that xcodebuild doesn't work when run as a user that has no home directory, like daemon. It throws its toys out of the pram in as baroque a manner as it can muster.

STEP 5: Create a "jenkins" user

So, to solve this we can either have Jenkins run as one of the existing users, or - more cleanly - create a new user specifically for jenkins.

To do this:

  • Create a user called "jenkins" from Control Panel. If you care particularly, you might want to create a "hidden" user; follow the instructions here: http://hints.macworld.com/article.php?story=20080127172157404
  • Stop jenkins again: sudo launchctl unload -w /Library/LaunchAgents/org.jenkins-ci.plist
  • Edit  /Library/LaunchAgents/org.jenkins-ci.plist, change the username entry from daemon to jenkins
  • Change all permissions on the existing jenkins files: "sudo chown -R jenkins /User/Shared/jenkins" "sudo chgrp -R staff /User/Shared/Jenkins"
  • Restart Jenkins: sudo launchctl load -w /Library/LaunchAgents/org.jenkins-ci.plist
Re-start the build. Sit and wait.


Job done

From memory, that was the set-up steps required to get builds to work on a Mac from a fresh Jenkins install. These things aren't really covered by the install guides. They're obvious once you know them. Hindsight is great like that.

Plenty of people followed my whining on Twitter with disbelief, saying that Jenkins "just works" for them. Others suggested moving over to Hudson instead, but I imagine I'd've had the same issues there.

Perhaps I'm unusual, and this stuff does just work for everyone else. If that's not the case, then I hope this rant proves useful.

As a postscript, I now have my Jenkins server working well. I have configured a Windows client, running under a Parallels virtual machine on the same computer. It's not the fastest build server when both run together, but it's passable.

There are definitely some rough edges and features lacking from Jekins, but I can't complain at the price. And there are plenty of excellent plugins that really do make it a very capable build server.


Friday, 12 August 2011

Pushing a git repository into an existing subversion repository

I worked on a project using git as the version control system. Eventally I needed to share it with other developers, who had an existing corporate Subversion repository. They didn't want to be bogged down in the minutae of learning a new version control system.

So I had to push the code in my git repo up to the svn repo.

There are two options:
  1. Take a baseline of the code and just comit that to svn, losing all version history. It's simple; it's quick; it works. Ten points for getting the job done. No points for elegance. And minus several thousand points for losing revision history.
  2. Serialise the development history in git and use that to re-vivify the history within Subversion. Many, many, points for doing the right thing. Minus quite a few for the faff it takes to work out how to do it.
Clearly, (2) is the way to go.

For your delight, this is how I finally managed to do it. Hopefully it'll help you avoid similar head scratching and Googling.


How to push a git repository into svn

Obviously, we'll want to invoke the git-svn command. The trick is how to arrange your git repo so that it's tracking the subversion repository correctly.


Step 1: Create the landing point in the svn repo

svn mkdir svn://DEST/repo/projectname/{trunk,branches,tags}

It's worth noting that in this example, I was happy to just clone the mainline of development, and ignore any git branches.

As you can infer, the corporate svn repo has many top-level directories that are all themselves "mini-repos". This is why I had to push the git history into an existing svn repo, rather than just create a new svn repo.


Step 2: Create a git svn clone tracking svn

git svn clone svn://DEST/repo/projectname/trunk dest

Now we have a git repo that tracks the destination svn landing point for the import operation.


Step 3: Track the git repo we want to import

cd dest
git remote add -f source /path/to/git/source/repo

Now, if you inspect the git history (for this I used the excellent GitX (L) ), you'll see a whole series of commits from the original git repo and, disconnected from this, the master HEAD plus a git-svn HEAD pointing to the original (single) svn commit we cloned.


Step 4: Rebase the original git repo onto git-svn

Here's where the secret magic lies. I seems like there are many ways to go from here. This was the only one I found to work. Of course, I tried many ways that failed. Once I found one that worked, I stopped trying. So if there's a better way I'd love to hear it, but this seems to work well.

git rebase --onto remotes/git-svn --root source/master

At this point, I realised that my git history wasn't strictly linear; I had worked on a few machines, so the history of trunk wove arond a bit.

This meant that what I had expected to be a straightforward operation (that's what you'd expect with a SVN hat on) required a few rebase fix-ups along the way:

(
gvim foo # fix merge conflict
git add foo
git rebase --continue
)
# ... rinse and repeat

These were required because branches in the source repo from work on different machines that got merged together to form the "source" trunk line of development didn't flatten into a rebase without a few tweaks.

In general, the conflicts were small and weren't hard to fix.


Step 5: Admire your work

git log

You should now see that the entire master development line of the source git repo has been replayed into the master of your working repo, stacked on top of the git-svn point.

Again, GitX (L) helped to visualise this.


Step 6: Push up to svn

Now that we've arranged everything above git-svn, it's a simple case of:

git svn dcommit

To push the changes up into svn.

Wednesday, 25 May 2011

Optimising Parallels performance for development

I use the wonderful Parallels 6 to perform all my Windows development. (I find working on a Mac makes Windows development a lot more bearable - at least for this old Unix-head).

In general, Parallels works superbly (and is reported to perform a lot better than VMware, if you believe the hype). However, for operations like rebuilding a large, complex C++ source tree, the virtual machine performance lagged a long way behind a native machine. Large compiles can take more than twice the time of a real Windows PC. Clearly, this taxes the host machine hard: hammering CPU, memory, and disk at once.

This problem exhibits on my four core Mac Pro with as many resources as I could throw at the problem, as well as on my more humble MacBook Pro.

I performed a number of experiments to work out how to fix this:
  • Tweaking the allocated CPU cores, memory, and disk space
  • Tweaking the settings for the virtual hard drive
  • Network building from host mac file system
None of these made much difference. In fact, I was somewhat surprised that operating on a networked disk was fantastically slower. That was a shame, as it would be advantageous to share a single source tree with my Xcode development for cross-platform development. (As it happens, I manage this by having a Windows-side git clone of the git repo on the Mac side).

However, I've now managed to get my compile times right down. Here's how.

Do bare in mind that these tweaks are in addition to the obvious steps you should take with any machine:
  • Have as fast a CPU as possible.
  • Throw as many CPU cores as you can at the problem - builds can be parallelised very easily.
  • Throw as much memory as you have at your disposal at the problem.

1. Swap the swap

The factor slowing me down the most turned out to be the Parallels virtual disk that Windows was running on. First, the swap file was hosted on it. So I made a second virtual disk, and pushed the virtual memory off onto it. That made a small, but appreciable difference.

2. Only ever use fixed size disks

In your disk settings, do not use automatically expanding disks. That's just another overhead for the computer to manage whilst accessing disks. Create a fixed size blob of disk space and run with it.

3. Use a virtual SCSI disk

This is the big one. So pay attention at the back.

It seems that Parallels can emulate a SCSI disk far, far faster than it can emulate and IDE disk. However, it defaults to creating IDE disks. I believe that this is to make installation of Windows simpler, as you don't have to fettle with custom SCSI drivers during installation.

You can't just switch the main disk from IDE to SCSI, though. Windows has a minor eppe and refuses to run if you do that. I couldn't be bothered to wipe it all and try to reinstall on a new SCSI virtual disk, so I added yet another large SCSI virtual disk for my source trees and checked out onto that disk.

Remember: it's a fixed size, non-expanding SCSI disk.

With this configuration the build simply screams in comparison to building on the virtual IDE C: drive.


I hope you find this information useful!

Wednesday, 15 July 2009

How to move your iTunes media onto a new hard disk

I run iTunes on Mac OS. I'm at the latest version (8.2 at the time of writing).

I have filled a hard disk with 11,000 tracks, many videos, podcasts subscriptions, and applications. I like to keep a separate hard disk for all my iTunes use, distinct from the main drive. This drive contains the audio, video, and the iTunes database files.

Having filled up my media disk, it was time upgrade to a larger disk in the same machine. It's not too hard if you let iTunes manage your music manually, just follow this HOWTO.

However, I like to manage my files manually. I have a directory structure for files which separates them according to use (I use my media with programs other than iTunes, but you need iTunes to sync with iPods). iTunes permits, but doesn't like this.

Moving the iTunes media onto a new disk is hard because:
  • iTunes does not cope well with its database files being moved
  • I sync with a number of iPods and an iPhone. Don't want to lose sync with those devices.
  • The iTunes database file is a closed binary format, and not easy to edit.
(On the mac, at least) iTunes is clever enough to track file movements on the same disk. You can rearrange your media files, and iTunes won't get confused. This is true for HFS+ at least (perhaps iTunes is tracking files by ID rather than filename, I never worried how it works). However, iTunes cannot cope with files moved between disks, which makes migrating your iTunes database somewhat complex.

There are a number of good HOWTOs on the net for this kind of thing (see the references at the end), but they all didn't quite describe what I wanted to do exactly.

So here's my HOWTO. If you know any better versions of these steps, let me know.

Prerequisites:
  1. You have installed the new drive, and formatted it, etc.
  2. You can see new drive at same time as old drive.
Steps...
  1. Quit iTunes. Best not to have it updating the database or downloading podcasts whilst you're working on it!
  2. Copy entire contents of old media disk to new one, including all your media and the "iTunes" directory full of database files, application downloads, podcasts, etc.
  3. For safety's sake, I renamed the "iTunes" folder on the old disk to try to prevent iTunes from using it again and confusing matters. Based on iTunes cleverness, it might have spotted the rename magically - perhaps it would have been better to archive the old "iTunes" directory and delete the original?
  4. Go to new media drive. Look in iTunes directory. Open the "iTunes Library" file - it's iTunes's binary-format database. Open it with a text editor, select everything in it, and delete it all. Save the file. Ensure it has size zero.
  5. Open the "iTunes Library.xml" file in the same directory in a text editor (this is a XML human-readable version of most of the data in the database). Do a global search and replace for all "/Volumes/OldMediaDriveName" to "/Volumes/NewMediaDriveName" (changing those names appropriately, obviously).
  6. Start iTunes with the Option (alt) key held down. It asks for you to provide the location of a new iTunes data file. Select the new drive's iTunes directory.
  7. Get ready for a long wait. iTunes will now rebuild it's binary database from the XML file. For a large database this takes a VEEEEERY long time. I was waiting for over 30 minutes (on a PPC Dual G4, to be fair). Answer nagging questions as required. Trashing the iTunes database loses a lot of important, but non-essential information like album art associations, window setup, etc. iTunes will spend a while churning through all your albums trying to download cover art, work out volume normalisation, etc.
  8. Sort out the applications you have downloaded. Look under "Applications" in iTunes' source list and you'll see that iTunes hasn't picked and of them up. Drag all the "*.ipa" files from your "iTunes/iPod Games" and "iTunes/Mobile Applications" directories into the Applications view. They'll magically appear. Purchased applications will copy over fine.
  9. Sort out your podcast subscriptions. Sadly, they've been lost, too. Despite some tutorials descriptions, I can't easily find a way resubscribe. You'll have imported a load of podcast mp3 files which have genre "Podcast" - you can see them in your library with a simple search. The corresponding podcast subscriptions have been lost. You can therefore see the podcasts you were subscribed to; their feed URLs is available in the "Get Info" iTunes dialogue box for each file. You'll have to resubscribe manually.
That's it. We're all done. You can now sync your iPods fine. Sync settings are NOT lost, thankfully.

References

Tuesday, 7 July 2009

(Becoming a) Git

I wanted to learn something new. I hadn't had much exposure to distributed version control systems. So took the plunge and installed git. Throwing caution to the wind, I relied on it immediately for critical project work. It was an interesting, and not entirely unpleasant experience.

I chose git for a couple of reasons:
  • people I knew had been using it, and gave me favourable reports
  • it has good svn (Subversion) integration

  • I know people who favour bzr (Bazaar). However, git seems the more powerful puppy, and the one that might teach me more overall.

    So far, I think that git is a very, very good tool. However, even though it's becoming more mature, it is not a friendly beast and not for the timid.

    Becoming distributed

    There are plenty of good articles floating around the net that describe the advantages of DVCS over the traditional centralised model. It makes a lot of sense. Even so, centralised version control isn't going anywhere soon.

    The main advantage of git for me is the svn integration. My project's repository is held on the other side of the Atlantic and I'm attached to it by a thin wet string, so access times to the repository are pitifully poor. Running something like git provides me with a local mirror so query operations are far faster, and I have the ability to make "local" checkins that are versioned but not yet pushed up to the central svn for public consumption.

    Both of these are neat tricks.

    Installation

    I've installed git on Linux, MacOS and Windows. Naturally, the Linux install was the easiest. I pulled it in through Kubuntu's package manager, and everything worked swimmingly.

    The Windows port is interesting. Since Windows is not sufficiently Unix-like to run Git in any sane way, the nice Windows distributors ship with a minimal bash environment. For this old Unix-head it's a wonderfully useful thing, and saves me reaching for cygwin so much. It might be a bit of a bodge, but I like it.

    I'm doing most of my work on Mac OS at the moment. There are a few ways to get git on the mac, but the Git on MacOS installer project seems to most sensible (at least, at first glance). It works well enough, however, its still not running perfectly for me. The svn integration is bust. The git svn dcommit script doesn't complete correctly. After each subversion commit the tool needs to do a git svn rebase. However its internal script paths are incorrect and this always generates an error. So you have to manually git svn rebase to sort it all out. If you forget to do this all sorts of chaos ensue as repos get out of date, and not all of your changes propagate upstream.

    Using git

    Like most DVCS you certainly have to have some kind of idea what's going on before you dive straight into git usage. Git has a quite steep learning curve, and it's documentation is still not at the same level as other tools, no matter what you may hear from other people. Many problems must be resolved by Google searches rather than looking in the "git book".

    General git workflows are simple and pleasant, though. To this old Subversion-head, the idea of staging the changes you will make prior to checking them in at first seemed clunky. However, after a few commits I have really come to like the workflow. And the fact you can cherry pick individual parts of a file to commit is very neat indeed.

    The git stash is also a cute feature, allowing you to temporarily park the changes your working on (effectively in a short-lived temporary branch), to do something else, and then to reapply your changes once you're ready to come back to them.

    Tool support is a lot sparser than other version control systems. The command line distributions all ship with a Tcl/Tk application called gitk which is remarkable useful and powerful, albeit crap-to-look-at in an early 1980s stylee. On the mac there is gitx which is cute, but not quite as powerful as gitk.

    Complex merges seem harder to resolve in git than other systems, but this might entirely be because of a lack of understanding on my part. There is a lot more power under the hood, that for sure. But it makes harnessing it a struggle. But this is a feature: git was not designed for idiots.

    It's discomforting to come from a place where you know your version control tool inside out to a place of relative ignorance. But it's Good For You to make this jump every now and again. It puts hairs on your chest. (If you're female, you might not want to do this too often, then.)

    SVN integration

    Apart from the Mac install issue, I've mostly found using git as a local svn mirror to be remarkably effective.

    I have found, however, that its best to keep each git repository separate, each a clone of the main svn repo. I have a number of machines which I build the code on. I'd initially hoped to make one svn clone repo, then clone repos on the other machines based on that one git clone. The clones work OK, but pushing back the changes appears to cause all sorts of confusion and lead to some bogus git svn dcommits at the top of the git tree.

    This problem became so bad that I gave up on the idea of a fan-out repository structure, and just cloned each repo from svn individually on each machine. This seems lumpy, and does mean there's more trans-atlantic svn traffic than I'd like. I believe that Bazaar is much better in this respect, but would like to hear it confirmed by someone more knowledgable.

    The future is bright. The future is git.

    I've had a few hiccups along the way, but I'm happy enough to keep going with git. There are plenty of advanced use cases I've yet to encounter, and I dread and look forward to the pain in equal measure.

    Git is the C++ of version control systems

    My observation based on a few months of use is that git is the C++ of version control systems. This is ironic based on what Linus thinks of C++. However git is the powerful,-can-do-everything,-allows-you-to-shoot-yourself-in-the-foot-if-you-don't-know-enough-about-it version control system. People will be prejudiced against git because of its complexity. Some people will love it because of its complexity and power. Sometimes it's the best tool for the job, though.

    Git: it's good for you. Just like C++.

    Thursday, 12 March 2009

    Software: Dropbox

    This week I was given a referral to try the beta version of Dropbox. I was impressed.

    Dropbox is a simple file synchronisation service for multiple computers. It's your granny's rsync, if you like. Installation is simple, as is signup. You point the software at a magic folder that it will keep in sync with every other computer tied to your Dropbox account. It's simple, fast, and works well.

    The free version offers 2G of space. You can pay for more, if you need it. If you're not on a machine with Dropbox installed there's a web interface for you to access your files.

    It's working really well for me. I'm working on my presentation for this year's ACCU conference, and Dropbox is making my life easier. Rather than carry around the presentation with me to edit at work or at home, I just save it in my Dropbox folder, and the latest version is ready for me to edit wherever I am.

    Check it out.

    Wednesday, 26 November 2008

    (Another) MacBook Pro hard drive upgrade (17" model)

    In October I performed surgery on my 15" MacBook Pro, to upgrade the hard drive. Today I've been repeating the performance, but on a 17" MacBook Pro.

    A few observations on the different models:
    • Upgrading the 17" model was easier. (Partly because I've done it once before, and partly because it's generally a more accessible machine.)
    • The screw patterns are identical. However, the Phillips screws inside the battery cover are far more accessible than on the 15" model; they're angled so you can get a screwdriver to them without contorting your hand.
    • The lid seems to crack off of a 17" model with greater ease - less fiddly plastic interlocking.
    • There's more use of sticky tape inside a 17" machine!
    • The nubs that hold the drive in the laptop chassis are different on the 17", asymmetrical in design. I wonder why the two models differ like this?

    Friday, 7 November 2008

    Kubuntu 8.10 on Parallels

    Kubuntu 8.10 is out, full of KDE 4 goodness (honestly, that's not sarcasm - KDE4 is quite usable these days). I've been running it under Parallels on Mac OS, and there's good news and bad news...

    The good news

    Kubuntu 8.10 works really well under the beta of Parallels Desktop 4. But it's not out yet, and we're not allowed to talk about it. You never heard it from me.

    The bad news

    Kubuntu 8.10 does not work under the current release version of Parallels Desktop 3. As soon as KDE4 attempts to start, the video mode goes wobbly and X restarts. kdm goes on an infinite start-crash-start-crash loop. It's great fun for the first thirty restarts or so.

    So what's going wrong? I'm not entirely sure. You can start X by hand fine. And you can run X apps, so it wouldn't appear to be a video support problem. I've been tinkering with bits of the startkde script. The failure stems from the call to the ksmserver, which handles the majority of the bringing up the KDE session. It's around about here that my enthusiasm for debugging left, and I escaped back into Parallels betaland for a simpler experience.

    Helpfully, if you try to start a failsafe X session under Parallels 3, it fails for entirely different reasons.


    Friday, 31 October 2008

    A MacBook Pro hard drive upgrade

    I have just upgraded my 15" Macbook Pro with a larger hard drive. The machine was shipped with a 120G hard drive when I bought it. Times move on, and data accumulates. Cubase projects and Parallels virtual machines quickly fill up precious space.

    Hard drives are not a user-upgradable component of these notebook models, but there are plenty of descriptions of how to disassemble a MacBook Pro available on the net. To their credit, MacBook Pros are relatively easy to pull apart and very well-made machines. Still not as serviceable as an IBM (or Lenovo, or whatever they're called these days), but not bad at all.

    The upgrade is perfectly simple for anyone with technical competence, a little bravery, and a torx size 6 screwdriver.

    The drive

    I installed a 320G Western Digital Scorpio drive, which seems a very good choice. It's a high-performance 7200RPM drive. WD claim that it consumes a comparable amount of power as an equivalent 5400RPM drive - a claim I can't validate this yet, except to say that battery life doesn't seem significantly shorter than with the previous drive.

    A jump from 5400 to 7200RPM is great. The result is a snappier machine which handles better when running many tracks at once in Cubase. Software build speeds are marginally faster. The machine boots more quickly, too, but I tend to reboot infrequently anyway.

    Running XBench tests before and after give compelling results:
    • Sequential uncached writes increase from 18.3MB/sec to 55.5MB/sec
    • Sequential uncached reads increase from 9.1MB/sec to 19.7MB/sec
    • Random uncached writes increase from 9.8MB/sec to 31.7MB/sec
    • Random uncached reads increase from 8.2MB/sec to 24.93MB/sec
    Installation

    The only interesting part of the process was working out how to migrate my old data onto the new drive.

    Previously, I've performed a Leopard install with the old drive attached over USB; the Mac OS installer magically notices the old drive and offers to migrate the data over. I tried this. but it didn't go as planned - not all the data migrated over (a whole load of components and programs didn't move across) and the installer still forced me to register and add a new user, despite there being a number of users that had just migrated over. Less than full marks, then. I wonder whether this was due to the Leopard version on the old disk being ahead of the install DVD version?

    There are suggestions that a Time Machine backup is a good migration strategy. But I fear that this will fail in pretty much the same way.

    The solution is simple, though:
    • Boot the machine from the Leopard install disk.
    • Select Disk Utility from the Tools menu.
    • Partition the new drive with a suitable partition table to boot an Intel machine. Create a single journalled HFS+ partition.
    • Click on the "Restore" tab and restore data from the old drive (make the old drive the Source) onto the new drive (make the new drive the Destination).
    • Ensure that Erase desination checkbox is selected.
    • Click on OK.
    • The old data is copied onto the new drive's parition.
    • You now have a carbon copy of yor old drive, covering the entire surface of the new drive.

    Thursday, 11 September 2008

    New DisplayLink mac driver

    Fortune smiles on the brave. Or, perhaps in my case, on the bored.

    Today I remembered a problem I suffer running the beta DisplayLink mac os driver, and so took a quick detour to their mac beta driver website. It was a way to amuse myself whilst compiling my 20th broken version of gcc (but that's another story).

    It turns out they released a mac driver update less than a week ago. Well, hurrah! Surprising they made no mention of this on their blog.

    They claim the update provides: 2D acceleration, improved video playback, and increased stability, as well as addressing several bug fixes. So with excitement I downloaded and installed the new goodies. I haven't messed around with it enough to say how much faster 2D performance is, but it'll be interesting to have a play.

    Sadly, however, my original problem still has not been fixed. I have a number of USB pendrives (with chips from SMI Corporation, Product ID 0x1000 and Vendor ID 0x090c) that will no longer mount on the mac when the DisplayLink drivers are installed. It's a shame that I can only use my nice 8G USB drive by starting Parallels and accessing it as a shared drive.

    Hopefully they'll be able to solve this problem soon. Or I'll have to cycle up Castle Hill with a baseball bat in my hand and have a quiet word :-)

    Wednesday, 11 June 2008

    Do you know your tools?

    The crafty aspects of programming (as in, the aspects that are like a craft, not the aspects that are cunning like a devious weasel hatching a dastardly plot) require us to use tools to fashion our work. Like any other artisans, we're reliant on quality tools to help us quickly produce software masterpieces. You could produce an elegant sculpture using only an blunt nail file, brute force, and perseverance, but you'd be better off using a full set of sharp chisels, points, claws, and hammers. They sure do help.

    Good tools are important, but we also need to know how to use them. To be really productive, we really need to know how to use them - so their use is second nature. When we achieve this, we don't have to get distracted by using the tools, and our attention can be devoted fully to the code we're crafting, not the tool we're driving.

    A friend of mine plays keyboards in a band. Recently he bought himself a new instrument - a top-of-the-line monster machine that can make tea and toast, all while you play incredible keyboard licks using only one finger. It's got loads of functions, and there's a lot to learn about it. Even the simple functions are hidden amongst the complex array of knobs and buttons.

    He took the keyboard out to a gig not long after having bought it, and it all went spectacularly wrong. The keyboard seemed to have a mind of it's own, wouldn't behave itself at all, and after a while stopped making sounds at all.

    Convinced it was faulty, he arranged to have it shipped back to the manufacturer and repaired (under guarantee, naturally). But they sent it straight back. Nothing was wrong with it, he just had no idea how to use it. His lack of understand of his tool had caused the problem.

    Not knowing his tool cost him in two ways: he performed badly when it mattered most, and he wasted time and money needlessly (it's not cheap to post one of those large beasts). When you're counting on them, it's really important to know how to use your tools.

    Do you know how to use your tools? Properly? What tools are you using? Could you be more productive using them? Are there better tools you could be using right now?

    TIP
    Know your tools. Know what's in your toolbox.

    Thursday, 5 June 2008

    A !Zap colour scheme for Vim

    It's common knowledge that Vi (well, Vim) is the best editor in the world, with no exception. I have used Vim for the majority of my programming career, and I love it. It's as much a way of thinking - a way of life - as it is an editor.

    Before using Vim, when incarcerated on Acorn computers, I used an editor called Zap (or !Zap if you're that way inclined). It was a really powerful little beast, with great support for different filetypes and awesome syntax highlighting. It was the power of Zap that forced me to look for a similarly powerful editor... Vim.

    Ever since my move to Vim I've been using a custom colour scheme that made Vim look more Zap-like. A few other people have used it over the years, but it's always been a few random lines pasted into my .vimrc file, rather than a proper Vim colourscheme.

    Well, that is, until now. Vim users rejoice, here is my Zap colorscheme file for Vim. Save this as ~/.vim/colours/zap.vim and then add "colorscheme zap" to your ~/.vimrc file.

    Enjoy.

    " =============================================================================
    " Name: zap
    " Purpose: Zap-like colour scheme
    " Maintainer: Pete Goodliffe (pete@goodliffe.net)
    " Last change: January 2008
    " =============================================================================

    " Zap is an archaic editor from RISC OS (an archaic computer)
    " But it was great.

    " =============================================================================
    " Preamble
    " =============================================================================

    set background=dark

    hi clear

    if exists("syntax-on")
    syntax reset
    endif

    let colors_name = "zap"

    " =============================================================================
    " Vim >= 7.0 specific colours
    " =============================================================================

    if version >= 700
    hi CursorLine term=underline cterm=underline guibg=#111133
    " hi CursorColoumn
    " hi MatchParen
    " hi Pmenu
    " hi PmenuSel
    endif

    " =============================================================================
    " General colours
    " =============================================================================

    hi Normal guibg=Black guifg=White ctermbg=Black ctermfg=White
    hi Cursor gui=none guibg=White guifg=Black ctermbg=White ctermfg=Black

    hi Folded guifg=Orange guibg=DarkBlue
    hi FoldColumn guifg=Orange guibg=DarkBlue

    " The following values have never been set by my vimrc, but this these are the
    " default values that I end up using...

    "NonText xxx gui=bold term=bold cterm=bold ctermfg=4 gui=bold guifg=Blue
    "LineNr xxx term=underline cterm=bold ctermfg=3 guifg=Yellow

    "hi StatusLine xxx term=bold,reverse cterm=bold,reverse gui=bold,reverse
    "hi StatusLineNC xxx term=reverse cterm=reverse gui=reverse
    "hi VertSplit xxx term=reverse cterm=reverse gui=reverse
    "hi Title xxx term=bold cterm=bold ctermfg=5 gui=bold guifg=Magenta
    "hi Visual xxx term=reverse cterm=reverse guibg=DarkGrey
    "hi SpecialKey xxx term=bold cterm=bold ctermfg=4 guifg=Cyan

    " =============================================================================
    " Syntax highlighting
    " =============================================================================

    hi Comment gui=none term=bold guifg=Green ctermfg=Green
    hi Todo gui=bold term=bold guibg=yellow guifg=black
    hi Constant term=underline guifg=#8dffff
    hi Identifier gui=bold term=underline guifg=#ffff60
    hi Function gui=none guifg=#ffcabd
    hi Type gui=bold term=underline guifg=#aaaa00
    hi Statement term=bold guifg=#ffff20
    hi PreProc term=underline guifg=#00bbff ctermfg=LightBlue
    hi Special term=bold guifg=Orange

    hi Search gui=underline guifg=#fe0000 guibg=#553333
    hi QtClass guifg=Orange ctermfg=LightBlue
    Oh, and if you're looking for an excellent version of Vim that runs on Mac OS, the check out MacVim.

    Thursday, 15 May 2008

    Cross compiling Boost

    Boost is a truly excellent C++ library, and something that all C++ programmers should be familiar with. It's a set of peer-reviewed extensions to the standard C++ library and is an excellent weapon in your C++ arsenal. Many core Boost libraries have gone on to be adopted in the C++ standard itself. I love it.

    Mostly.

    Building the Boost library is a swine. Seriously annoying. For most users, this isn't an issue. You can get binary versions for most platforms, and almost every Linux (or other Unix platform) distribution has a pre-packed version available. So that's fine. And to be fair, most of the Boost libraries are header-only (plenty of template mumbo-jumbo), so often it's irrelevant anyway.

    But if you need to build Boost yourself you enter a weird world. Boost uses a homegrown variant of Perforce's Jam (which they call bjam - amusingly remeniscent of a 1980s UK white goods retailer). That's a little unusual, but fine. Then they layer their own build file magic on the top. That's fine. And then they document it. That's fine.

    Apart from the bit where it's really hard to work out how to use it to do anything other than a simple build. For example, it's really, really hard to work out how to make the gcc build process use your own gcc compiler, rather than the standard gcc on $PATH. It's a real shame that such an excellent library requires you to become an expert in their non-standard build system in order to build it!

    We run C++ on embedded ARM devices, so we cross compile to ARM from x86 Linux boxes. I recently needed to update our toolchain (from gcc 3.x to gcc 4), and I had to jump from Boost 1.33.x to 1.35 (the former had bugs when compiled with gcc 4). This newer Boost version saw subtle build system changes, and (IMVHO) a worsening of the build documentation.

    In case you need to do the same thing - cross compile Boost with your own custom compiler - here's my recipe (this is for Boost 1.35, the process is annoyingly different for previous versions):

    First you must make Boost jam. If you have a different jam it may not work. Specifically, if you want to use Cygwin you must use the correct jam from Boost not the Cygwin-supplied bjam, or things don't work in weird ways...

    cd tool/src/jam
    ./build.sh
    cp bin.*/bjam
    PATH=:$PATH
    cd -

    Now, here's the magic. Brace yourself. This is how you use a custom gcc compiler, you write some odd rule into some very well hidden config file:

    echo "using gcc : 4.2.2 : PATH_TO_DIR/arm-softfloat-linux-gnu-g++ ; " > tools/build/v2/user-config.jam

    Obviously, tweak the version numbers to your requirements. Then use your fresh copy of jam to build Boost, changing the configuration magic below as you require...

    bjam -d2 \
    --toolset=gcc
    '-sBUILD=release static multi/single' \
    link=static \
    --prefix= \
    --layout=system \
    --with-XXX --with-XXX \
    install

    And that should do the trick. (The --with-XXX lines specify which libraries you'd like built, e.g. "--with-thread --with-signals --with-filesystem")

    Now, I'm not claiming that this recipe is the best way to do it. But from a lot of reading, it's the only half-way sane method that I've found. For example, it's possible to put symlinks to your custom toolchain early in your path, but that strikes me as a very clumsy way to persuade the Boost build system to use your compiler.

    There is one problem thyat I have observed with this approach: it only uses your custom g++ compiler, but still uses the system ar. As it happens, this works fine (at least, it does for static libraries, which is what we use). Perhaps another using line in the randomly located jam config file might solve this?

    That's my recipe. If you have to cross compile Boost then: good luck!

    Tuesday, 13 May 2008

    Must-have Apple software

    I used to use Linux as my primary platform. I'm now officially an Apple fanboy. I've had Macs for a while, but now I'm a total convert. The user experience rocks, and it's still Unix under there. And Cubase on the Mac works far, far better than anything on Linux.

    There's loads of freeware available that's useful, but here's my shortlist of the genuine must-have Apple software, from an I-was-a-Linux-weenie point of view:
    • MacVim - The best port of (the best text editor) Vim to the Mac.
    • NeoOffice - Very good native port of OpenOffice, the multi-platform Microsoft Office replacement. OpenOffice will soon have a native Mac release, but until then this is great.
    • Adium - A multi-protocol instant messenger
    • Transmission - Sweet little torrent client
    • Audacity - Simple but capable audio editor
    • MacFUSE (and MacFusion) - Native filesystems for many protocols (ssh, NTFS, and many many more). MacFusion is a cute menubar GUI to make using MacFUSE more convenient.
    • The Unarchiver - Better than the built-in file decompression utility. Simple and unobtrusive.
    • The Gimp - The well-known image processing package. Sadly, runs under X11 - not a native app.
    • MacSword - An awesome interface to the Sword bible study package.
    • iRed Lite - Allows you to use the Apple remote to do all sorts of useful things (I've used it as a remote presentation controller)

    Plugins and utilities:
    • Growl - Notification system for MacOS. Many applications support growl notifications.
    • Afloat - Useful program that allows most application's windows to be pinned to the top of the window stack. Watch a quicktime movie easily whilst working on a document!
    • Inquistor - Awesome Safari search plugin. Calls itself "Spotlight for the web". I can't argue with that,
    • MenuMeters - System profile utility that puts info up in the menu bars. Very useful to see how much CPU Cubase is eating up!
    • OpenTerminalHere - Great Finder plugin that opens a terminal window with the working directory set to the current finder path.
    Commercial software I highly recommend:
    • Parallels - The infamous utility that lets you run Windows at the same time as Mac OS. It is truly awesome.
    • Cubase - Well, to be fair, there's a ton of muso application's I'd recommend, like the incredible TruePianos and many, many more.

    Before leopard, there were other packages that were important to me:
    • iTerm - Tabbed terminal window. Now redundant as the Leopard terminal has been vastly improved.
    • Desktop Manager - Virtual desktop application. Now replaced by Leopard's built-in spaces feature. Interestingly, this application still plays very nicely with Leopard's spaces.