The underlying architecture of Mac OS X executables was built from the beginning with flexibility in mind. This flexibility has become important as Macintosh computers have transitioned from using PowerPC to Intel CPUs and from supporting only 32-bit applications to 64-bit applications in Mac OS X v10.5. The following sections provide an overview of the types of architectures you can support in your Mac OS X executables and how
Hardware Architectures
64-Bit Support
Object File Formats
Debug File Formats
Runtime Environments
When Mac OS X was first introduced, it was built to support a 32-bit PowerPC hardware architecture. With Apple’s transition to Intel-based Macintosh computers, Mac OS X added initial support for 32-bit Intel hardware architectures. In addition to 32-bit support, Mac OS X v10.4 added some basic support for 64-bit architectures as well and this support was expanded in Mac OS X v10.5. This means that applications and libraries can now support four different architectures:
32-bit Intel (i386)
32-bit PowerPC (ppc)
64-bit Intel (x86_64)
64-bit PowerPC (ppc64)
Although applications can support all of these architectures in a single binary, doing so is not required. That does not mean application developers can pick a single architecture and use that alone, however. It is recommended that developers create their applications as “universal binaries” so that they run natively on both 32-bit Intel and PowerPC processors. If performance or development need warrants it, you might also add support for the 64-bit versions of each architecture.
Because libraries can be linked into multiple applications, you might consider supporting all of the available architectures when creating them. Although supporting all architectures is not required, it does give developers using your library more flexibility in how they create their applications and is recommended.
Supporting multiple architectures requires careful planning and testing of your code for each architecture. There are subtle differences from one architecture to the next that can cause problems if not accounted for in your code. For example, the PowerPC and Intel architectures use different endian structures for multi-byte data. In addition, some built-in data types have different sizes in 32-bit and 64-bit architectures. Accounting for these differences is not difficult but requires consideration to avoid coding errors.
Xcode provides integral support for creating applications that support multiple hardware architectures. For information about tools support and creating universal binaries to support both PowerPC and Intel architectures, see Universal Binary Programming Guidelines, Second Edition. For information about 64-bit support in Mac OS X, including links to documentation for how to make the transition, see “64-Bit Support.”
Mac OS X was initially designed to support binary files on computers using a 32-bit architecture. In Mac OS X version 10.4, however, support was introduced for compiling, linking, and debugging binaries on a 64-bit architecture. This initial support was limited to code written using C or C++ only. In addition, 64-bit binaries could link against the Accelerate framework and libSystem.dylib only.
In Mac OS X v10.5, most system libraries and frameworks are now 64-bit ready, meaning they can be used in both 32-bit and 64-bit applications. The conversion of frameworks to support 64-bit required some implementation changes to ensure the proper handling of 64-bit data structures; however, most of these changes should be transparent to your use of the frameworks. Building for 64-bit means you can create applications that address extremely large data sets, up to 128TB on the current Intel-based CPUs. On Intel-based Macintosh computers, some 64-bit applications may even run faster than their 32-bit equivalents because of the availability of extra processor resources in 64-bit mode.
Although most APIs support 64-bit development, some older APIs were not ported to 64-bit or offer restricted support for 64-bit applications. Many of these APIs are legacy Carbon managers that have been either wholly or partially deprecated in favor of more modern equivalents. What follows is a partial list of APIs that will not support 64-bit. For a complete description of 64-bit support in Carbon, see 64-Bit Guide for Carbon Developers.
Code Fragment Manager (use the Mach-O executable format instead)
Desktop Manager (use Icon Services and Launch Services instead)
Display Manager (use Quartz Services instead)
QuickDraw (use Quartz or Cocoa instead)
QuickTime Musical Instruments (use Core Audio instead)
Sound Manager (use Core Audio instead)
In addition to the list of deprecated APIs, there are a few modern APIs that are not deprecated, but which have not been ported to 64-bit. Development of 32-bit applications with these APIs is still supported, but if you want to create a 64-bit application, you must use alternative technologies. Among these APIs are the following:
The entire QuickTime C API (not deprecated, but developers should use QuickTime Kit instead in 64-bit applications)
HIToolbox, Window Manager, and most other Carbon user interface APIs (not deprecated, but developers should use Cocoa user interface classes and other alternatives); see 64-Bit Guide for Carbon Developers for the list of specific APIs and transition paths.
Mac OS X uses the LP64 model that is in use by other 64-bit UNIX systems, which means fewer headaches when porting from other operating systems. For general information on the LP64 model and how to write 64-bit applications, see 64-Bit Transition Guide. For Cocoa-specific transition information, see 64-Bit Transition Guide for Cocoa. For Carbon-specific transition information, see 64-Bit Guide for Carbon Developers.
Mac OS X is capable of loading object files that use several different object-file formats, including the following:
Of these formats, the Mach-O format is the format used for all native Mac OS X application development. The Java bytecode format is a format executed through the Hotspot Java virtual machine and used exclusively for Java-based programs. The PEF format is handled by the Code Fragment Manager and is a legacy format that was used for transitioning Mac OS 9 applications to Mac OS X.
For information about the Mach-O file format, see Mac OS X ABI Mach-O File Format Reference. For additional information about using Mach-O files, see Mach-O Programming Topics. For information about Java support in Mac OS X, see “Java Support.” For information about the PEF format and Code Fragment Manager, see “CFM Runtime Environment”
Whenever you debug an executable file, the debugger uses symbol information generated by the compiler to associate user-readable names with the procedure and data address it finds in memory. Normally, this user-readable information is not needed by a running program and is stripped out (or never generated) by the compiler to save space in the resulting binary file. For debugging, however, this information is very important to be able to understand what the program is doing.
Mac OS X supports two different debug file formats for compiled executables: stabs and DWARF. The stabs format is present in all versions of Mac OS X and until the introduction of Xcode 2.4 was the default debugging format. Code compiled with Xcode 2.4 and later uses the DWARF debugging format by default. When using the stabs format, debugging symbols, like other symbols are stored in the symbol table of the executable; see Mac OS X ABI Mach-O File Format Reference. With the DWARF format, however, debugging symbols are stored either in a specialized segment of the executable or in a separate debug-information file.
For information about the DWARF standard, go to http://www.dwarfstd.org. For information about the stabs debug file format, see STABS Debug Format. For additional information about Mach-O files and their stored symbols, see Mach-O Programming Topics.
Since its first release, Mac OS X has supported several different environments for running applications. The most prominent of these environments is the Dyld environment, which is also the only environment supported for active development. Most of the other environments provided legacy support during the transition from Mac OS 9 to Mac OS X and are no longer supported for active development. The following sections describe the runtime environments you may encounter in various versions of Mac OS X.
The dyld runtime environment is the native environment in Mac OS X and is used to load, link, and execute Mach-O files. At the heart of this environment is the dyld dynamic loader program, which handles the loading of a program’s code modules and associated dynamic libraries, resolves any dependencies between those libraries and modules, and begins the execution of the program.
Upon loading a program’s code modules, the dynamic loader performs the minimal amount of symbol binding needed to launch your program and get it running. This binding process involves resolving links to external libraries and loading them as their symbols are used. The dynamic loader takes a lazy approach to binding individual symbols, doing so only as they are used by your code. Symbols in your code can be strongly-linked or weakly-linked. Strongly-linked symbols cause the dynamic loader to terminate your program if the library containing the symbol cannot be found or the symbol is not present in the library. Weakly-linked symbols terminate your program only if the symbol is not present and an attempt is made to use it.
For more information about the dynamic loader program, see dyld. For information about building and working with Mach-O executable files, see Mach-O Programming Topics.
The Java runtime environment consists of the HotSpot Java virtual machine, the “just-in-time” (JIT) bytecode compiler, and code packages containing the standard Java classes. For more information about Java support in Mac OS X, see “Java Support.”
The Code Fragment Manager (CFM) runtime environment is a legacy environment inherited from Mac OS 9. Mac OS X provides this environment to support applications that want to use the modern features of Mac OS X but have not yet been converted over to the dyld environment for various reasons. The CFM runtime environment expects code modules to be built using the Preferred Executable Format (PEF).
Unlike the dyld environment, the CFM runtime environment takes a static approach to symbol binding. At runtime, the CFM library manager binds all referenced symbols when the code modules are first loaded into memory. This binding occurs regardless of whether those symbols are actually used during the program’s course of execution. If a particular symbol is missing, the program does not launch. (An exception to this rule occurs when code modules are bound together using weak linking, which explicitly permits symbols to be missing as long as they are never used.)
Because all system libraries are implemented using Mach-O and dyld, Mac OS X provides a set of libraries to bridge calls between CFM code and system libraries. This bridging is transparent but incurs a small amount of overhead for CFM-based programs. The Carbon library is one example of a bridged library.
Note: The libraries bridge only from CFM to dyld; they do not bridge calls going in the opposite direction. It is possible for a dyld-based application to make calls into a CFM-based library using the CFBundle facility, but this solution is not appropriate for all situations. If you want a library to be available to all Mac OS X execution environments, build it as a dyld-based library.
On Intel-based Macintosh computers, CFM binaries are run under the Rosetta environment.
The Classic compatibility environment (or simply, Classic environment) is called a “software compatibility” environment because it enabled Mac OS X to run applications built for Mac OS 9.1 or 9.2. The Classic environment is not an emulator; it is a hardware abstraction layer between an installed Mac OS 9 System Folder and the Mac OS X kernel environment. Because of architectural differences, applications running in the Classic environment do not share the full advantages of the kernel environment.
The Classic environment is supported only on PowerPC-based Macintosh computers and is deprecated in Mac OS X v10.5 and later. You should not be doing any active development using the Classic environment. If you want to write programs to run in Mac OS X, you should use the dyld environment instead.
The Classic environment is not supported on Intel-based Macintosh computers.
Last updated: 2007-10-31