Important: The information in this document is obsolete and should not be used for new development.
ZeroLink speeds application development time by eliminating
the link process from development builds. Instead, Xcode generates
an application stub that contains the full paths to the object files
that make up the application. At runtime, each object (.o)
file is linked as it’s needed. This works only when running your
application within Xcode. You cannot deploy applications using ZeroLink.
To turn ZeroLink on or off, use the ZeroLink (ZERO_LINK) build setting. ZeroLink is enabled by default in the Development build style. If you build with this build style, you automatically get ZeroLink functionality. See “Build Styles” for more information on using build styles. ZeroLink works only for native targets.
The following sections explain how you can customize ZeroLink to further reduce application launch times and identify issues you must keep in mind when using ZeroLink.
Customizing ZeroLink
Caveats When Using ZeroLink
ZeroLink postpones the linking of object files until the last
moment possible. However, there are some symbols that, by default,
are always resolved (that is, the corresponding object files are
linked against the application and the code is executed). These
symbols are static initializers in C++ and +load methods
and categories in Objective-C. You can tell ZeroLink not to search
the object files of your application for these symbols to reduce
the application’s launch time.
There are situations that require the initialization of objects
before a program’s main function
is called. For example, a class may declare global variables that
can be accessed by other code before the class has a chance to initialize
them. In Objective-C, the +initialize method
may be executed too late (see “Initializing a Class Object” in The Objective-C 2.0 Programming Language. The purpose of static initializers in C++ and +load methods
in Objective-C is to provide developers with a mechanism to initialize
variables at the earliest possible point during a program’s launch
process. In Objective-C–based applications, categories are also
loaded before main is
called.
When you build an application, the static linker adds the
standard entry-point function to the main executable file. This
function sets up the runtime environment state for the kernel and
the application before calling main,
which involves calling static initializers for C++ code and loading
categories and invoking +load methods
for Objective-C code.
When using ZeroLink, you can further reduce the launch time
of the application by postponing the execution of static initializers
and +load methods, and
the loading of categories. But you must be certain that code in
your application doesn’t rely on static initializers or +load methods
being called before main or
on categories being loaded before main is
called. Otherwise, your application may crash or behave unexpectedly.
There are three linker options you can use to customize ZeroLink in your project. To use these options, add them to the Other Linker Flags (OTHER_LDFLAGS) build setting:
-no-run-initializers-before-main:
If an application contains C++ code, the linker looks for static
initializers at launch time before calling main in
all the object files that make up the application and, if it finds
any, links the object files containing them into the application.
This may slow down application launch. If you’re developing an application
using C++ and it doesn’t depend on static initializers being run
before main, use this
option to prevent ZeroLink from scanning object files in search
of static initializers before calling main.
Keep
in mind that if there’s code that requires that static initializers
be run before main, your
application could crash. This specially true for applications that
use static initializers to register code with a registry. If the
sole purpose of the static initializers is to perform the registration
(that is, if no other code would ever trigger the execution of the
static initializers by accessing a global variable, for example),
no registration would take place. For example, when reading a serialized
file, the reader reads the name of the class of each serialized
object and tells the class to reconstruct an instance from the data. In
C++ there is no infrastructure to look up a class by name. Instead,
a common idiom is for each class capable of serializing and deserializing
instances of itself to register its class name and deserialization
method address with the reader using a static initializer.
-no-load-categories-before-main:
If an application contains Objective-C code, the linker looks for
categories at launch time before calling main in
all the object files that make up the application and, if it finds
any, links the object files containing them into the application.
As with -no-run-initializers-before-main,
this may slow application launch. If your application doesn’t
depend on categories, use this option to prevent ZeroLink from scanning
object files in search of categories before calling main.
Some
developers rely on the use of categories in the implementation of
their class hierarchies. In such a model, the implementation of
a class spans one or more categories of that class. Using this design
model, a program may run incorrectly when the categories that implement
additional class functionality are not loaded. With ZeroLink, classes
can be loaded when need because there’s a direct reference to
them, but ZeroLink cannot load categories dynamically. Therefore,
if your application depends on categories, it may crash or behave
unexpectedly if you use the -no-load-categories-before-main flag.
-no-run-load-methods-before-main:
Similarly to -no-load-categories-before-main,
ZeroLink scans object files for +load methods
in Objective-C code before main is
invoked to link them to the application. Using this option prevents
the scanning of object files for +load methods
before ZeroLink calls main. +load methods
in Objective-C are similar to static initializers in C++: They are
executed early during application launch, before main is called,
to perform tasks that must be performed at the earliest possible
time. However, the order of execution of +load methods
is not guaranteed. If your code depends on +load methods
to be run before main,
your application may crash or run incorrectly if you use this flag.
When building an application that uses static libraries (.a files),
each static library is linked to produce a bundle. At runtime, each
bundle is loaded on demand. If your application starts slowly while
using ZeroLink and has a large number (100 or more) of object files,
you can try adding an intermediate static library target, containing
the relatively stable parts of your source code. This gives you
the best of both worlds: static (build time) linking for stable
code and dynamic (runtime) linking for code that changes frequently.
If you want to view information about the loading and linking
of object files as your application runs, set the ZERO_LINK_VERBOSE environment
variable to any value. The information appears in run log of the
application or stderr.
These are some things you should keep in mind when using ZeroLink:
ZeroLink
doesn’t support the use of private external symbols; that is symbols declared
as __private_extern__.
Private
external symbols are visible only to other modules within the same
Mach-O file as the modules that contain them. If you use a private
external symbol in your project while ZeroLink is turned on, you
get an unknown-symbol error when your code tries to access it. For
example, if you have the definition __private_extern__
int my_extern = 800; in a source file and
the declaration extern int my_extern; in
another source file, when the second module accesses my_extern,
your application exits with the following log output:
ZeroLink: unknown symbol '_my_extern' |
MyApplication has exited due to signal 6 (SIGABRT) |
For more information on private external symbols, see “Scope and Treatment of Symbol Definitions” in “Executing Mach-O Files” in Mac OS X ABI Mach-O File Format Reference.
When setting breakpoints on methods, you must use full method
specifiers, not just selectors. For example, if your project has
a class named MyClass with an instance method called myMethod,
you must specify a breakpoint on myMethod like
this:
-[MyClass myMethod] |
If you get an error similar to this one:
dyld: /Users/user_name/MyApp/build/MyApp.app/Contents/MacOS/MyApp Undefined symbols: |
Foundation undefined reference to _objc_exception_set_functions expected to be defined in |
/System/Library/PrivateFrameworks/ZeroLink.framework/Versions/A/Resources/libobjc.A.dylib |
delete /System/Library/PrivateFrameworks/ZeroLink.framework/Versions/A/Resources/libobjc.A.dylib.
You
would get this error if you install the Xcode tools in a system
with a prerelease version of Mac OS X. The libobjc.A.dylib file
contains a developmental copy of the Objective-C runtime. It’s
not necessary for normal development.
Last updated: 2006-11-07