On 2009-11-17 03:19:39 -0500, Don <[email protected]> said:
Steven Schveighoffer wrote:
On Mon, 16 Nov 2009 16:07:56 -0500, Walter Bright
<[email protected]> 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
[email protected]
http://michelf.com/