Mac OSX 10.6 preference panes and ARC - macos

Can I run a preference pane built using ARC and x86_64 (10.9 SDK) and targeted for 10.6 under 10.6 or will it only run under 10.8 or later? I keep getting "GC compatibility mismatch errors" when I try to launch it under 10.6 and 10.7

64-bit preference panes in 10.6 and 10.7 have to use garbage collection, not ARC. See this question for more.

You will have to download an older version of Xcode (5.0.2, I think) that supports Garbage Collection in order to build the 64-bit pref-panes.
Or you could build a 32-64-bit prefpane, which the older OSes will attempt to load the 32-bit one after failing to load the 64-bit one. Note that you will need to either compile it using manual retain count, or have some bridging functions to handle retain and release.

Related

How do you debug an app for an older version of Mac OS X?

I am developing an app using Xcode 4.6 on an OS X 10.8 machine. The app deployment target is set to 10.6, which is what we need to support. But when I archive the app (compile, link and embed resources+frameworks) and deploy (aka copy) it to the 10.6 test machine, it crashes with a generic Segmentation fault. It works fine on 10.7.
I can't compile the project in Xcode on the older Mac because the app is built using the newer compiler (it uses ARC, implicit property synthesis, the new objective-c literal syntax, etc.). It also wouldn't type check because the base SDK is 10.8 and it references some 10.8 tokens which the compiler on the 10.6 machine doesn't know about.
Any suggestions on how to go about debugging the app?
I'm not affiliated with this company/software in any way, but Deploymate is a paid app which can scan your app for SDK usage and tell you when you are calling selectors and APIs that are unavailable on older OS versions. This can help you track down exceptions and crashes relating to API usage.
You are very likely using one or more 10.7+ APIs that crash on 10.6. With a 10.8 target SDK you allow all the calls to function that are available in that SDK. However apps are bound late so this doesn't crash when you do not actually call those functions. You need an explicit check similar to this (here for the full screen feature):
#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6
if (runningOnLionOrLater) {
[mainWindow setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary];
[toggleFullscreenItem setHidden: NO];
}
#endif
One way to determine the current version is:
int macVersion;
if (Gestalt(gestaltSystemVersion, &macVersion) == noErr) {
runningOnLionOrLater = macVersion > MAC_OS_X_VERSION_10_6;
}
For debugging the problematic calls simply set the base SDK to 10.6 and XCode should mark those functions that are not available there.
While there is no real good solution to this (I've seen simply different behaviors on different macOS versions) and no way to simply simulate an older macOS version, if you have a machine to spare:
It is possible to use an external HD, partition it and install different macOS versions. They all can be bootable and it's a matter (pain) of restarting the machine for every OS version.

Using xcode 4 but targeting OSX Leopard (10.5) and above

I was developing an application using xcode 4 to target snow leopard (10.6)
Now, nearly the end of the development, I've been asked to support 10.5+.
I have set the Mac OS deployment target to 10.5 and compiled.
The compiler (LLVM 2.0) and linker seems to be happy with the change
but I came across a feature I've used from NSWindow (isOnActiveSpace) which is states as AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER
This I understand states that it won't work (throw exception?) in 10.5 but no warning were raised when building.
I currently don't have a leopard installation and it will take our QA some time to arrange a computer for that, so in your experience, what should I do next? how can I go over the code and make sure that all the APIs I've used are in fact safe for 10.5?
Set MAC_OS_X_VERSION_MAX_ALLOWED to 1050 and see what symbols disappear. More info in TN2064.

how do I build a universal binary with xcode 3.2.6?

I am using XCode 3.2.6 on an Intel Mac running OS X 10.6, to build a fairly simple app that needs to be able to run under OS 10.4 on a PPC-based Mac, in addition to modern Intel-based Macs.
Under the project settings, I only see options for 32-bit Intel, 64-bit Intel, and Standard (32/64 Intel). Should I be seeing a "Universal Binary" entry here?
I don't have any problem running it under 10.4 on an Intel Mac. I was careful not to use features that don't work under 10.4, and I think I set the project settings correctly to allow it to be backward-compatible to 10.4. It's just that I can't figure out how to get it to compile for PPC.
I'm flailing around, trying to figure out how to build a universal binary, and I think I'm probably just missing something obvious. Any help would be greatly appreciated.
You don't have to choose one of the predefined settings for the Architectures build setting. You can choose "Other..." and then explicitly enter a list of architectures like ppc, i386, x86_64.
By the way, there are extra tricks if you need to run on G3s: You must use GCC 4.0 and the 10.4 SDK.

Can I use LLVM (in Xcode) to compile an application targeted at OS X 10.5 and up?

The readme for Xcode 3.2.5 (PDF) says:
Using the LLVM compiler requires the 10.6 SDK
Does this mean that the LLVM compiler (not LLVM GCC) can only be used to compile applications targeted at 10.6 and up, or just that the 10.6 SDK has to be present for the LLVM compiler to work?
You can target 10.5 using the LLVM compiler in either Xcode 3.2 or 4. I have been doing this for our control software for more than half a year, and it runs just fine on the Leopard machines we've deployed on.
As with all cases where you build with one SDK and target another, you'll need to verify that you don't use any features specific to the newer OS without appropriate runtime checks and / or weak linking of certain frameworks.
Based on a quick test, I was able to build a 10.5 app with LLVM using the latest Xcode, 3.2.5, which includes the 10.6 SDK. Having checked the product, the Info.plist records the minimum OS version as 10.5 and as far as I'm aware, the original choice of compiler has no effect on the way the OS runs the end product (as you'd expect). Unfortunately I don't have a 10.5 machine to test it on.
I'd therefore imagine that Apple just mean that LLVM ships with the 10.6 SDK.

How do you enforce the minimum OS requirements in a Cocoa app?

My app needs to run on 10.4 or later. If I launch it on 10.3 it just fails to launch or crashes.
How do you tactfully enforce minimum system requirements? Can you customize the message it shows?
Add a key to your applications Info.plist, specifying LSMinimumSystemVersion as 10.4.X for whatever X you need as a minor version. For more, see Apple's documentation.
I have not used either of these techniques/advice, just passing along the information I have gathered.
You might try something like the SystemVersionCheck “shim” executable to provide a working OS version check for versions that do not honor LSMinimumSystemVersion (e.g. 10.3).
The pre-compiled executable is PPC-only. You might need to rebuild it to support PPC and Intel machines so that it works with 10.3, but also so that 10.6 users are not prompted to needlessly install Rosetta. I found a blog entry that has a hint on how to setup the PPC build to target 10.3 and the Intel build to target 10.4u (it was written about 10.5 and Xcode 3.0 though—do the latest versions of Xcode even include the 10.3 SDK?).
If you experience a crash after adding the LSMinimumSystemVersion key to your app's plist manually, then this is due to the Finder not recognizing the changed state of the app properly. Either restart the Finder (e.g. log out) or duplicate the app in the Finder. The copy will then behave correctly.

Resources