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