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/

Reply via email to