Post by Markus ZinggPost by Patrick MachielseTo be precise, Carbon is a cleaned up version of the old Mac OS API's.
Any pointer to this specification / documentation?
<http://developer.apple.com/carbon/>
and
<http://developer.apple.com/documentation/Carbon/Carbon.html>
Post by Markus ZinggPost by Patrick MachielseIt was created to make it possible to migrate programs written for (say)
Mac OS 7 to Mac OS X.
Does "migrate" mean recompiling sourcecode or is such software binary
compatible among mac os versions?
In 1984, Macs were introduced with files with resource forks.
Applications were files of type 'APPL', with a resource fork containing
'CODE' resources. Resource 'CODE' 0 held a segment descriptor table,
and resources 'CODE' 1..n held the executable code for the segments.
Operating system calls were accessed through Motorola TRAP instructions.
These TRAP instructions are specified in the .h files, for example if
you look in Quickdraw.h in the :Universal:Headers:CIncludes: folder,
you'll see stuff looking like:
void PaintRect(const Rect * r) ONEWORDINLINE(0xA8A2);
where ONEWORDINLINE is a macro, which, on a 68K compiler, tells the
compiler everything it needs to generate a call to the O.S.
In the '90s, when Apple switched to the PowerPC, they added PowerPC
executable code in PEF, the "Preferred Executable Format" for the
PowerPC architecture, defined by IBM, the source of the PowerPC chip.,
usually in the data fork, and if an application contained a 'cfrg' 0
resource, then PowerPC macs would use it to find the PowerPC executable
code, while 68k macs would continue to execute the 68k version of the
application. That way, you could have a single file that would appear as
an application in the Finder, and run correctly on either 68K or PowerPC
Macs. Applications that had both 68K and PowerPC code would get the
"native" one loaded on the specific Mac they were running on that time,
so would not just run on all Macs, but would run as fast as possible on
the current Mac, they were known as "fat" applications.
The switching was very fast, and the user could use a mix of 68k and
PowerPC programs seamlessly, without caring about which was which.
The PowerPC doesn't use a TRAP instruction to access the O.S., instead
it uses a scheme where you must link against a "stub library", and when
the user trys to run the program, the loader component of the operating
system matches the stub library with actual shared libraries that are
kept in the :System Folder:Extensions: folder. This is the DLL Hell
problem familiar to Windows users, saved only by the Mac's lack of a
fragile registry.
Apple also added the "Mixed Mode Manager", a convention for wrapping
function pointers that decorates them with info for how they should be
interpreted. Using the Mixed Mode Manager, PowerPC programs could call
68k plugins, and 68K programs could call PowerPC plugins, and each could
call callback routines in the other processor architecture. Different
linker formats were also supported, for example original 68k and also
CFM-68k.
Then some people who were unaware of Apple's history and traditions took
over, and instead of extending the mixed mode manager and the cfrg
system, and instead of continuing with the executable format that the
PowerPC was designed for, they switched to the one that happened to come
from GNU's gcc (Mach-O). They also usurped the names of all the O.S.
calls, now the programmer links with either InterfaceLib (old style
PowerPC) or CarbonLib (new style PowerPC) stub libraries, and if Carbon,
adds a 'carb' 0 resource. Now the loader loads against InterfaceLib or
CarbonLib, and you are up and running. What this means is you can't have
a single file that is recognized and run as a native application on all
Macs: if it has PowerPC code, and that code uses CarbonLib, then it
won't run on early PowerPC Macs that don't have the CarbonLib shared
library installed. (It was an optional component before OS 9.)
The Carbon API is available on OS X still, both as PEF and as Mach-O,
but new development is only present in the Mach-O version. You can,
with some pain in a Carbon PEF program, programmaticly load a Mach-O
shared library into RAM and extract function pointers from it, and with
some pain, pass a PEF callback to a Mach-O call and vice versa, but it
is painful.
Instead of seamlessly running earlier apps, OS X starts a slow classic
Mac emulator, which only runs if the user has the optional OS 9
installed. the emulator, called "Classic" takes about a minute to start,
so a Mac user usually says, "Oh, Shit" the first time he double clicks
on a classic app after booting his OS X machine.
There was a third-party post-linker for the Metrowerks C/C++ compiler
called FatCarbon that got around this problem, and let you build an app
that had two copies of your PowerPC code in it, one that linked with
InterfaceLib, and one with CarbonLib, and FatCarbon would arrange for
the CarbonLib version to be used if the shared library for CarbonLib was
actually present.
So, there we stand: classic 68K code resources, PowerPC in PEF format
linked against InterfaceLib, PowerPC in PEF format linked against
CarbonLib, PowerPC in Mach-O format, all generated from the same source
code, but you can't package all of them usefully into a single file that
will be recognized as an executable application on all Macs. What you
can do is: register your four-byte application signature on Apple's web
site (you should do this anyway), and make the document's icon look like
an app. The real apps would be buried in folder, automaticly launched
when you double click on the document (because the Finder has made an
appropriate desktop database on the partition that you cloned the CD
from.) that launches the appropiate app: bundled for OSX, otherwise
classic 68K code or InterfaceLib PowerPC PEF.
Hire an expert. Don't try to get all these details right on the first
Mac program you've ever written.