Wednesday, August 18, 2010

Writing screensavers for 10.5 and 10.6

I needed to write a screensaver recently, one that would work on both 10.5 and 10.6, but ran into a problem when I tried to build such a project on XCode 3.2. The problem is that with 10.6 the program that does the job of running the plugins that are ScreenSavers (.saver modules) runs in 64bit mode when possible. And since .saver modules are plugins, they also need to be able to run in 64bit mode. However, the 10.5 version of the ScreenSaver.framework only had 32bit modes (PPC and i386), and so you can't build x86_64 (64bit Intel) modules against it. Conversely things changed enough between 10.5 and 10.6 that modules build against the 10.6 SDK will not run on 10.5. Rock meet hard place.

The solution to this problem seems obvious in retrospect: build the 64bit module against the 10.6 SDK, and build the 32bit modules (PPC and i386) against the 10.5 SDK. I am proud to say that I came up with the idea of building two different .saver modules, and then choosing which one to run... but I did not want the hassle of having to maintain two codebases, or even two compiles. But luckily for me there are people who are much smarter than me who already solved the problem. So I tried closing my XCode project and trying to translate what Warren Dodge wrote about his older project file into my newer one. Eventually I got what worked, and then discovered how to to do it in the XCode GUI:

Step 1: Open the project inspector
figure 1To do this click on the blue icon at the top of the "Groups & Files" column in the main window of your project. Then click on the "Info" button on the toolbar, or select "Get Info" from the File menu. The should look something like this:
Step 2: Change the "Base SDK for all configurations" to 10.5
Circled in red on the figure 1, the "Base SDK" serves as a master switch for all of the configurations (usually "Debug" and "Release"). While the label might imply that it only sets the targeted SDK, this also changes the build target.
Step 3: Setup the Configurations
Click over to the "Build" tab, then make sure that the "Configuration" selector (circled in red) is set to "All Configurations". This will make sure that the rest applies to both "Build" and "Release" configurations. Then type "10.5" in the search box (to the right of the "Configuration" setting). This will narrow down the really big list to just a few.
Setp 4: Add the BaseSDK setting

Click on the "Base SDK" entry under the "Architectures" section to highlight it (circled in green). Then click on the gear box at the bottom of the page (circled in purple), opening a drop-menu. From this menu select "Add Build Setting Condition". That will add a row underneath the "Base SDK" row. Clicking on that will pop look something like this:

Select "Intel 64-bit" from the menu, then click on the "Mac OS X 10.5" from just to the right of it (the lower one of the two together, not the default one), and from its pop-up menu select "Mac OS X 10.6".

At this point when the compiler goes to work it will use the 10.5 SDK for PPC and i386, but use the 10.6 SDK for x86_64. We are almost there!

Step 5: Add the Deployment Target setting
This final step is very similar to that for the Base SDK. The difference is that you highlight the "Mac OS X Deployment Target" line under the "Deployment" section, then once you have added the "Build Setting Condition" with the gear menu you change the "Any Architecture" selection to "Intel 64-bit" and the "Compiler Default" selection to "Mac OS X 10.6". You can leave the "Any SDK" alone, or set it to "Mac OS X 10.6" either way it will have the same effect.

Now you can close the "Project Info" box, and when you hit compile the settings will be right to have the output work on 10.5 or 10.6 without going through any other tricks (other than getting your code right). The same trick would probably work with setting things to 10.4 for 10.4 compatibility, but my project did not require that (and then I could not have used ObjC 2.0 tricks that I like to use).

No comments:

Post a Comment