Building Mach-O Files

To create programs, developers convert source code to object files. The object files are then packaged into executable code or static libraries. OS X includes tools to transform source code into a running application or a shared library that can be used by one or more applications.

This article loosely describes how Mac apps are built, and discusses, in depth, the types of programs you can build. It describes the tools involved in the Mach-O file build process, explains the types of Mach-O files you can build, and talks about modules, which are the smallest linkable unit of code and data in the OS X runtime environment. It also describes static archive libraries, which are files that package a set of modules.

The Tools—Building and Running Mach-O Files

To perform the work of actually loading and binding a program at runtime, the kernel uses the dynamic linker (a specially marked dynamic shared library located at /usr/lib/dyld). The kernel loads the program and the dynamic linker into a new process and executes them.

Throughout this document, the following tools are discussed abstractly:

The Xcode Tools CD contains several command-line tools (which this document refers to collectively as the standard tools) for building and analyzing your application, including compilers and ld, the standard static linker. Whether you use the Xcode application, the standard command-line tools, or a third-party tool set to develop your application, understanding the role of each of the following tools can enhance your understanding of the Mach-O runtime architecture and facilitate communication about these topics with other OS X developers. The standard tools include the following:

Tools for analyzing Mach-O files include the following:

The Products—Types of Mach-O Files You Can Build

In OS X, a typical application executes code that originates from many types of files. The main executable file usually contains the core logic of the program, including the entry point main function. The primary functionality of a program is usually implemented in the main executable file’s code. See Executing Mach-O Files for details. Other files that contain executable code include:

To function properly in OS X, all object files except kernel extensions must be dynamically bound—that is, built with code that allows dynamic references to shared libraries.

By default, the static linker searches for frameworks and umbrella frameworks in /System/Library/Frameworks and for shared libraries and static archive libraries in /usr/lib. Bundles are usually located in the Resources directory of an application package. However, you can specify the pathname for a different location at link time (and, for development purposes, at runtime as well).

Modules—The Smallest Unit of Code

At the highest level, you can view an OS X shared library as a collection of modules. A module is the smallest unit of machine code and data that can be linked independently of other units of code. Usually, a module is an object file generated by compiling a single C source file. For example, given the source files main.c, thing.c, and foo.c, the compiler might generate the object files main.o, thing.o, and foo.o. Each of these output object files is one module. When the static linker is used to combine all three files into a dynamic shared library, each of the object files is retained as an individual unit of code and data. When linking applications and bundles, the static linker always combines all the object files into one module.

The static linker can also reduce several input modules into a single module. When building most dynamic shared libraries, it’s usually a good idea to do this before creating the final shared library because function calls between modules are subject to a small amount of additional overhead. With ld, you can perform this optimization by using the command line as follows:

ld -r -o things.o thing1.o thing2.o thing3.o

Xcode performs this optimization by default.

Static Archive Libraries

To group a set of modules, you can use a static archive library, which is an archive file with a table of contents entry. The format is that used by the ar command. You can use the libtool command to build a static archive library, and you can use the ar command to manipulate individual modules in the library.

In addition to Mach-O files, the static linker and other development tools accept static archive libraries as input. You might use a static archive library to distribute a set of modules that you do not want to include in a shared library but that you want to make available to multiple programs.

Although an ar archive can contain any type of file, the typical purpose is to group several object files together with a table of contents, forming a static archive library. The static linker can link the object files stored in a static archive library into a Mach-O executable or dynamic library. Note that you must use the libtool command to create the static library table of contents before an archive can be used as a static archive library.

The ar archive file format is described in OS X ABI Mach-O File Format Reference.

With the standard tools, you can pass the -static option to libtool to create a static archive library. The following command creates a static archive library named libthing.a from a set of intermediate object files, thing1.o and thing2.o:

libtool -static thing1.o thing2 -o libthing.a

Note that if you pass neither -static nor -dynamic, libtool assumes -static. It is, however, considered good style to explicitly pass -static when creating static archive libraries.

For more information, see the libtool and ar man pages.