The scene: 1996. Apple has just purchased NeXT, and programmers huddle together, cursing the devil-spawned end user. “Alas,” says one, “our mighty empire has fallen. Know now that our legacy shall live on, as a curse passed to all mankind.”
“What curse shall this be?” asks his brethren. “What artifact of our dark majesty shall we use to smite our enemies and leave them fearing our almighty glories?”
“Why,” replies the first programmer, “it shall be known as… the OS X frameworks mechanism!” All tremble.
When we last left our heroes, I was trying desperately to assemble a universal binary that would work on OS X 10.4 as well as on my OS X 10.6 machine. After some pain and agony, I asked The Great and Knowledgeable Icculus (a.k.a Ryan C. Gordon) for advice. He directed me to The Helping Friendly Book the recently open-sourced Lugaru makefile, wherein I found a series of baffling and arcane compiler flags and linker options. That said, I pasted them into the Dredmor makefile, and let ‘er rip. After some agonizing and pointing things at various other things, the compilation proceeded smoothly, and I found myself staring at about two thousand linker errors. The cause? While Dredmor itself now built in an OS X 10.4-tolerant fashion, the dynamically linked libraries that we use (SDL and its child libraries, libexpat, libogg/libvorbis, and curl) were not. I consulted Ryan again, but he had gone off to play with the Famous Mockingbird or something and so I was left alone.
First step: try to build SDL as a universal binary. No dice, at first. SDL ships with both an XCode project and a script called “get-fat.sh” or something like that, which I ran. Naturally, it didn’t work. A quick search of the SDL mailing list archives reveals that, no, that script wasn’t supported and that Sam Lantinga advises everybody to just use the XCode project. *sigh*
Second step: crack open SDL, build it as a universal binary using XCode. This works fine, except that the framework refuses to install itself anywhere.
Third step: try to build the other child libraries of SDL – SDL_TTF, SDL_Mixer and SDL_Image. Here is where the fun really starts: all three of them have a mixture of “get-fat.sh” scripts and XCode projects,. and there’s no indication for when any of them work. The shell scripts caused all sorts of wackiness where perfectly ordinary configure scripts would suddenly start crashing and burning, spitting out errors like “C++ preprocessor cannot generate code.” This was, of course, because the configure program suddenly was convinced that my compiler was a directory on the other side of the hard drive. The XCode scripts completely failed to build, producing between 12 and 83 compiler errors.
Fourth step: drink coffee.
Fifth step: a plan was hatched! On the LibSDL website, pre-built copies of the SDL frameworks exist. Would they work? Perhaps! Inspired, I downloaded a number of .dmg files, cracked open their contents, and dumped them in /Library/Frameworks on my machine. Then copy them into my .app bundle for Dredmor, and shove them in Contents/Frameworks where they should – magically – be found by the dynamic library loader. I closed my eyes, drank the Frameworks kool-aid, and hit the makefile again. Would my linker now link? Yes! Wonderful. (This nicely bypasses the “having to run mysterious tools on your EXE file” step of the previous set of instructions.)
Sixth step: remember that we use libraries that aren’t SDL libraries, and watch as my dreams come to a grinding halt. In particular, we use libexpat, an XML parsing library that, amongst other things, hasn’t been updated since 2007. Somehow, I was able to pass a sufficiently nasty collection of compiler and linker flags to configure to produce … a static library. Fortunately, libexpat uses a BSD-style license, so I can get away with static linking in this case.
Seventh step: decide to get rid of support for HTTP log uploading via curl entirely, as this hasn’t worked since early 2009.
Eighth step: finally, an executeable. Send the whole mess over to David, whose stupid Macbook started this whole mess.
Ninth step: David reports that he’s STILL getting the mysterious “This architecture is not supported” message. Argh! Drink more coffee.
Tenth step: Re-check makefile. Discover missing compiler flag. Re-insert it. Fix include path errors. Shove whole heaving mess back into SVN again… and we have a Macintosh redistributable.
Really, the problem today was that configure and universal binaries (or building with previous versions of the OS X Developer SDK) do not mix. I think this is a ploy by Richard Stallman, who firmly believes that every time you ship a commercial product for OS X you are secretly supporting the Fascist Oppressors. After this was done, I decided to start working on the OS X auto-updater. I got everything talking to our update server, and then the auto-updater decided to auto-update itself out of existence. It died as it lived – up to date, and possibly suffering from severe depression.
Is it time for more coffee yet?