Mac OS X and backward compatibility

Michel Fortin michel.fortin at michelf.com
Tue Nov 17 06:20:34 PST 2009


On 2009-11-17 03:19:39 -0500, Don <nospam at nospam.com> said:

> Steven Schveighoffer wrote:
>> On Mon, 16 Nov 2009 16:07:56 -0500, Walter Bright 
>> <newshound1 at digitalmars.com> wrote:
>> 
>>> Backward compatibility doesn't mean that the old systems have to 
>>> support new features. It just means that the old features continue to 
>>> work on the new systems. I have a lot of software built for Win95 that 
>>> still works fine <g>. Even the DOS programs still work.
>> 
>> Your argument was about building programs on MacOS 10.5 that crash on 
>> 10.4.  That's like building programs on Windows XP and expecting them 
>> to run flawlessly on Windows 98.
>> 
>> Although, I will say, having a Hello World executable throw a bus error 
>> is a little over the top in breaking backwards compatibility :)
>> 
>> -Steve
> 
> Apple is a bit over the top. It really seems they don't give a damn 
> about backwards compatibility. Yet they've stayed in business. I think 
> there's a lesson in that.

I'm not sure to what extent that's true. I can still compile my apps 
for Mac OS X 10.1 in the latest Xcode by setting 
MACOSX_DEPLOYMENT_TARGET to 10.1. This prevents the resulting binary 
from using linker features not available in 10.1.

To ensure availability for each symbol, Apple headers use macros 
(MAC_OS_X_VERSION_MIN_REQUIRED and MAC_OS_X_VERSION_MAX_ALLOWED, mapped 
to compiler flags −mmacosx-version-min=X and −mmacosx-version-max=X) to 
hide APIs not available for a given target OS version, and the compiler 
can then issue errors if you try to use them. Or it can weak-link 
symbols, allowing you to check at runtime for their availability.

In the latest Mac OS X (10.4 forward), those two macros also control 
renaming at compile time of some symbols in the standard C library. 
This is because they changed things for UNIX conformance but didn't 
want to change the behavior for previously compiled programs. So if you 
don't set correctly MAC_OS_X_VERSION_MIN_REQUIRED at compile time you 
might also get a non-working executable in older Mac OS X versions. For 
instance, here's the declaration for fdopen on Mac OS X 10.6:

	#if defined(__DARWIN_10_6_AND_LATER) && 
(defined(_DARWIN_UNLIMITED_STREAMS) || defined(_DARWIN_C_SOURCE))
	FILE	*fdopen(int, const char *) __DARWIN_EXTSN(fdopen);
	#else /* < 10.6 || !_DARWIN_UNLIMITED_STREAMS && !_DARWIN_C_SOURCE */
	FILE	*fdopen(int, const char *) 
__DARWIN_10_6_AND_LATER_ALIAS(__DARWIN_ALIAS(fdopen));
	#endif /* >= 10.6 &&_(DARWIN_UNLIMITED_STREAMS || _DARWIN_C_SOURCE) */

If you dig the macros a little, you see it can remap the function to 
symbol "_fdopen$DARWIN_EXTSN", "_fdopen$UNIX2003" or keep the original 
name, all depending on what the MAC_OS_X_VERSION_MIN_REQUIRED macro and 
others are set to.

Compiling a hello world with the MACOSX_DEPLOYMENT_TARGET environment 
variable set to 10.4 and both MAC_OS_X_VERSION_MIN_REQUIRED and 
MAC_OS_X_VERSION_MAX_ALLOWED set to 1040 should result in a binary 
compatible with 10.4. Or you can compile against the Mac OS X 10.4 SDK 
to get the same result.

It's true that backward compatibility isn't the default setting when 
compiling a program in Mac OS X: you must explicitly ask for it. But I 
don't think it's fair to say that Apple doesn't give a damn, otherwise 
all this complicated stuff wouldn't exist.

Here are some more details (although some things in this article are outdated):
<http://developer.apple.com/mac/library/technotes/tn2002/tn2064.html>

And this one is documenting symbol renaming:
<http://developer.apple.com/mac/library/releasenotes/Darwin/SymbolVariantsRelNotes/index.html>

-- 


Michel Fortin
michel.fortin at michelf.com
http://michelf.com/




More information about the Digitalmars-d mailing list