A few are special features of the Xcode application, but most are confi gured using build settings.. Per - fi le compiler fl ags are like build settings in that they have a specifi c sco
Trang 1414 ❘ CHAPTER 17 BUILDING PROJECTS
CUSTOMIZING THE BUILD
Using build settings, and a few specialized Xcode settings, it ’ s possible to customize hundreds of
details about your build
There are literally hundreds of build settings — and the number grows with each release of Xcode
Finding the build setting you ’ re looking for can sometimes be a challenge The build settings tab
displays a description of the selected build setting, and is the fi rst place to look when you ’ re hunting
for a build setting or wondering what a build setting does You can also set the search fi eld to search
the descriptions of build settings, which might also help you fi nd what you ’ re looking for
The next few sections cover many common ways of customizing your build process and products
A few are special features of the Xcode application, but most are confi gured using build settings
The later sections cover some of the more important build settings, especially ones that control the
build process itself and ones that might have non - obvious relationships This book can ’ t possibly
explain them all The following sections hit the highlights and point you toward the documentation
for the rest
Per - File Compiler Flags
The per - fi le compiler fl ags setting is a special place where the compilation of a single source fi le can
be modifi ed These are literal command - line arguments, set for a particular source fi le and target,
and passed to the compiler only when that source fi le is compiled Each source fi le has a separate
compiler fl ags setting for each target in the project, so you can specify one compiler fl ag when the
fi le is being compiled for one target and a different compiler fl ag when it is compiled for another
There are no templates or documentation for these options in Xcode You will need to consult the
compiler ’ s documentation to compose your argument list correctly
Open the Info window for a source fi le If the source belongs to the active target, a Build tab
appears in the Info window, as shown in Figure 17 - 33 You can only edit the compiler fl ags for
the active target To edit the compiler fl ags for a different target, you must close the Info window,
choose a new active target using the Project ➪ Set Active Target menu, and then open the Info
window for the source fi le again
FIGURE 17-32
Trang 2Per - fi le compiler fl ags are like build settings in that they have a specifi c scope; they are only passed
to the compiler when that specifi c fi le is being compiled for a specifi c target In terms of customizing the build process to your needs, compiler fl ags can be thought of as the very highest layer of build settings, overriding even the compiler settings in the command - line layer Just keep in mind that compiler fl ags settings are not part of the build settings architecture: they are not named variables, cannot refer to other build settings, are not added to the execution environment, and are not accessible to build scripts or external processes They are a feature supplied by the Compile Sources phase as one more way of fi ne - tuning the build process
Personally, I try to avoid per - fi le compiler fl ags when possible It ’ s an obscure feature that ’ s diffi cult
to document and correlate to the source fi le These per - fi le compiler fl ags are stored in the project document as part of source item, which presents another potential problem; removing the source item or adding the fi le to another project will discard its settings
Today, many compiler options can be specifi ed in the source fi le itself using #pragma , attribute , and other compiler - specifi c syntax My fi rst choice would be set any module - specifi c compiler options
in the source fi le, and use per - fi le compiler fl ags only as a last resort
Cross - Development
In Xcode, cross - development refers to developing a program for use in one or more different versions of Mac OS X It does not mean cross - platform development, or writing a program that runs on a multitude of different operating systems or architectures Cross - development allows you to produce a program that runs on a specifi c range of operating system versions (Mac OS X 10.3.4 through Mac OS X 10.5.0, for example) You can also produce applications that run only on a specifi c version or an application that will run on any version that supports the features it requires
Installing Cross - Development SDKs
Before you can even think about doing cross - development, you have to install the cross - development SDKs The standard Xcode Developer Tools installation includes recent cross - development SDKs, but SDKs for older operating systems may be optional installs, as shown in Figure 17 - 34 If you did not install the SDKs when you installed Xcode, quit Xcode and run the latest Development Tools installer again At the Custom Install screen, choose the optional Cross - Development support package or packages
FIGURE 17-33
Trang 3416 ❘ CHAPTER 17 BUILDING PROJECTS
To use cross - development, you need to choose two boundaries: the earliest version of the operating
system that your application can run on, and the latest version of the OS that it utilizes
Choosing a Target SDK
The latest OS version that your project uses is called the Target SDK For example, you might be
writing and developing your application using
Mac OS X 10.6, but your application only
uses features and APIs that were present in
Mac OS X 10.5, which should allow it run
smoothly on both In this situation, your
target SDK should be set to Mac OS X 10.5
The Target SDK setting is set for the entire
project in the project ’ s Info window, as
shown in Figure 17 - 35 You can set it using
the Base SDK build setting for individual
build confi gurations, or use the General tab
to set it for all confi gurations, as shown at the
bottom of Figure 17 - 35
When you set the target SDK, the compiler
and linker will fail if you refer to symbols,
functions, or types that did not exist when
that version of the operating system was
released Understand that this in no way
prevents your application from running on
later versions of the operating system
FIGURE 17-34
FIGURE 17-35
Trang 4It simply means that Xcode compiles your source code using the headers and frameworks defi ned by
an older version of the OS This ensures that you ’ re unlikely to use any newer APIs or constants that might cause your application to fail when run on an older OS There may be other reasons it won ’ t run, but the Target SDK isn ’ t one of them
It should be noted that the iPhone provides two target SDKs for each major release of the iPhone OS: a native device SDK and a companion simulator SDK.
When you build your iPhone or iPod Touch application for the simulator, you’re building your application using a different set of frameworks than those used
by the actual device Be aware that there are some subtle differences between the two, and you should thoroughly test all aspects of your application on a real iPhone or iPod.
Choosing a Deployment Target
The other boundary is the deployment target, set using the Mac OS X Deployment Target
build setting, as shown in Figure 17 - 36 This sets the earliest version of the operating system your
application will successfully run on Whereas the Target SDK setting is purely a build time setting, the Deployment Target setting is both a
development setting and a run time setting
At build time, this setting fl ags certain
framework and library references as weak A
weak library reference lets your application link to a function that was introduced in a later OS, but still load on an earlier system that lacks that function (That doesn ’ t mean you can successfully call that function in the legacy environment, it just means the program will load and start running without it.) This setting is also included in the Info
plist of your application bundle and tells the operating system not to allow your application to load if the minimum operating system requirement is not met This may not have anything to do with what features your application uses; maybe you have simply never tested your application on Mac OS X version 10.4 and you don ’ t want anyone else trying
Both of these boundaries have defaults that are set for new projects The default for the Target SDK
is Current OS In other words, it compiles and links using the operating system frameworks and libraries currently installed on your development system The default for the Deployment Target is Compiler Default, which really means “ none ” The operating system will do its best to load and link
FIGURE 17-36
Trang 5418 ❘ CHAPTER 17 BUILDING PROJECTS
your application to the available APIs at run time Your application will fail to load if it has “ hard ”
links to APIs that don ’ t exist
Cross - Development Building
So how does this all work? When you installed the SDKs, you put a complete set of system
frameworks for each major version of the operating system in the /Developers/SDKs folder Each
folder contains a complete copy of the headers, frameworks, and dynamic libraries that shipped
with that version of the operating system, except that all of the executable code has been removed;
so - called “ stub ” libraries
When you choose a Target SDK in the project, Xcode sets the SDKROOT build settings This is the
path used by the compiler and linker to read all of the system headers and libraries your program
links to (I recommend not trying to change its value using a build setting.) When you set the Target
SDK for iPhone OS 3.0, it is just as if you were writing and compiling your program on an iPhone
running 3.0 The compilers and linkers know nothing about new features added in later versions of
the OS, and will complain if you try to use them This should prevent you from using any features
unique to the iPhone OS version 3.1, which might make your app incompatible with 3.0
Cross - Development Deployment
The Deployment Target is a little more complicated The headers in the SDK use the MACOSX_
DEPLOYMENT_TARGET and IPHONEOS_DEPLOYMENT_TARGET settings to defi ne special macros These
macros identify API symbols that did not exist in earlier versions of the operating system The value
of the build setting determines which symbols are affected For example, say your application refers
to a function that was added in iPhone OS 3.0 If run under iPhone OS 2.2.1, that function isn ’ t
present Normally this would cause your application to fail before it even started By compiling your
application with an iPhone OS deployment target of 2.2.1, it tells the compiler and linker to make a
special weak reference to that symbol in the system framework Your program will load and run on
an iPhone running 2.2.1, even though that particular routine isn ’ t present in the 2.2.1 frameworks
Calling a missing function is still a very bad idea You’ll have to add code to your application to determine conditionally whether that function is available — hint,
a weak reference to a missing symbol will be NULL — and avoid calling it when it’s not.
There are a number of limitations to using the deployment target Here are a few:
Cross - development is only supported for native targets
Weak linking only works in Mac OS X 10.2 and later, and even then not all cross -development features are available in 10.2
You cannot use the system ’ s umbrella header fi le as your program ’ s prefi x fi le That is, you can ’ t set your project ’ s prefi x fi le to /System/Library/Frameworks/Carbon.framework/
Headers/Carbon.h That ’ s because this isn ’ t the correct header if you ’ ve chosen a different
➤
➤
➤
Trang 6SDK Create your own header that does nothing but include the current framework header,
as follows, which will automatically include the Carbon.h header from whatever SDK you have selected:
#include < Carbon/Carbon.h >
A number of other, more obscure limitations and caveats exist To fi nd out about them, refer to the
Cross - Development Programming Guide included with the Xcode documentation, or online at
http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/
weak linking for functions in a newer version of the OS, and then check to see if those functions are available at run time
Building Universal Binaries
Prior to 2004, Xcode only produced PowerPC executable binaries That ’ s because this was the only processor architecture that Mac OS X supported Since then, Apple Computer has added two new architectures to its OS pantheon (64 - bit PowerPC, Intel 32 - and 62 - bit), along with new processors (ARM) for its consumer lines of iPhone and iPod Touch products Xcode can compile your program for any or all of these architectures when you build your project It does so by repeatedly compiling your application, once for each architecture, and then storing all of the resulting versions in a single multi - architecture binary (MAB) fi le — a fi le format that Mac OS X has supported for a long time Binaries that contain executable code for multiple architectures are referred to as Universal Binaries
Choosing the Architecture Set
To determine which architectures you want to build, set the Architectures ( ARCHS ) build setting; you will fi nd it in the Architectures group When you click the setting name, an architectures pop - up menu appears Select the architecture, or architecture set, that you want to build
The Architectures ( ARCHS ) setting is a space - delimited list of architectures to be built Xcode supplies a number of build settings that contain predefi ned sets of useful architecture lists, such as
ARCHS_STANDARD_32BIT , which will build only the 32 - bit variants of the processors that Mac OS
X deploys on (that is, PowerPC and Intel) The pop - up menu simply defi nes the ARCHS setting to equal one of these built - in settings, that is, ARCHS = $(ARCHS_STANDARD_32_BIT) The standard architecture macros supplied by Xcode are listed in the following table:
deployment
Trang 7420 ❘CHAPTER 17 BUILDING PROJECTS
When you ’ re building your project for release, ARCHS should defi ne the list of architectures your
application supports
For development, however, building multiple architectures is a waste of time; you typically test
on the system that you ’ re developing on, and you can only run and test code compatible with the
architecture of your development system That ’ s why the ARCHS build setting for the Debug build
confi guration is normally set to $(NATIVE_ARCH) , which is described next
Your Native Architecture
The NATIVE_ARCH build setting is the name of the architecture of the machine Xcode is currently
running on Setting ARCHS to $(NATIVE_ARCH) causes Xcode to only build the single, native
architecture when compiling applications and is intended for debugging A number of variations of
this build setting are listed in the following table:
For example, on the development system I ’ m using right now, NATIVE_ARCH is i386 (Intel), and
NATIVE_ARCH_ACTUAL is x86_64 (because I ’ m running on a 64 - bit capable system)
The Valid Architectures
The ARCHS setting is always tempered by the VALID_ARCHS build setting This setting does not
appear in the Xcode interface, but defaults to the list of architectures that Xcode knows how to
build Xcode only builds the architectures listed in this setting If you redefi ned VALID_ARCHS to ppc
ppc64 it would limit the project to producing only 32 - bit and 64 - bit PowerPC binaries, even if other
project settings requested other architectures
If you’re trying to create a conditional build setting and don’t know what value
to use in the arch= statement, use the shell script trick described in the “A Peek-A-Boo Build Script” section to dump all of ARCH variables There you will fi nd the exact architecture names that Xcode recognizes.
Finally, recompiling your program for another architecture is no guarantee that it will work Subtle
differences in pointer sizes and byte order can cause your application to fail If you need to build
a specifi c architecture for debugging and testing, set ARCHS to that specifi c architecture Refer to
the “ Universal Binary Programming Guidelines ” and the “ 64 - Bit Transition Guide ” in the Xcode
documentation for additional details
Trang 8Selected Build Settings in Detail
Build settings, like so many other details in software development, are easy to fi nd — as long as you already know where to look The catch - 22 occurs when you ’ re trying to fi nd something and don ’ t know what it is or where to fi nd it The following sections highlight hand - selected build settings that you should be familiar with, or are notoriously diffi cult to fi nd in the documentation
When listing Xcode - defi ned build settings, this book uses the form “ Full Title ( NAME ) ” to describe each setting Use its title when you ’ re looking for a setting in the Xcode documentation Use its name when referring to build settings in scripts or in build - setting value expressions Remember that copying a build setting will place its defi nition ( NAME=value ) on the clipboard
Build settings fall roughly into two categories: modifi able build settings that alter the behavior of the build process and informational build settings created
by Xcode The latter are not intended to be changed They are for use in other build setting values, custom scripts, and external processes and provide you with information about what is being built and how Changing an informational build setting can lead to undesirable results.
Browsing the build settings in the Build tab of the target or project can be very instructional
The major build settings are described here If you see a build setting that ’ s not covered in this chapter, search the Xcode documentation for its name The Xcode release notes cover most new and existing build settings There is also a Build Setting Reference document included in the Xcode documentation that describes many of these same settings
Products
The Product Name ( PRODUCT_NAME ) setting is, quit literally, the name of the product produced by the target To change the name of your target ’ s product, edit this build setting Note that the fi nal product name is actually a little more complicated if it includes an extension or is in a wrapper (bundle), but these are tacked on by other build settings
Info.plist Files
These settings control how the Info.plist fi le is generated for targets that produce bundles, as described in the following table
Info.plist File ( INFOPLIST_FILE ) This is the fi le in your project that will become the
Info.plist fi le for your product
Preprocess Info.plist File ( INFOPLIST_PREPROCESS )
If this fl ag is set, then INFOPLIST_FILE is run through the gcc preprocessor This allows you to use preprocessing macros and #if statements in your source Info.plist fi le
continues
Trang 9422 ❘ CHAPTER 17 BUILDING PROJECTS
Info.plist Preprocessor Prefi x File
( INFOPLIST_PREFIX_HEADER )
If your Info.plist fi le is preprocessed, this prefi x fi le
is read by the compiler fi rst
Info.plist Preprocessor Defi nitions
DEFINITIONS )
Space - separated list of macro defi nitions passed to the compiler when preprocessing the Info.plist fi le
Use this as an alternative to, or as an adjunct to, using a prefi x fi le
Search Paths
The search path settings determine where compilers and linkers look for headers and other fi les
referred to only by their name or partial path Each build setting is a space - separated list of paths If
a path itself contains a space or some other special character, it must be quoted in the list
Each path specifi es a folder to search If the path ends in ** , Xcode also searches any subfolders for
the fi le it is looking for Xcode always searches each folder for the fi le fi rst, before looking in any
subfolders
Many of the paths in these settings refer to headers and libraries in the system framework folders
These would be paths that start with /System/Library/Frameworks When you ’ re building using
a Target SDK, Xcode automatically prefi xes any system framework path with $(SDKROOT) so that it
correctly refers to the corresponding folder in the current SDK
Header Search Paths
( HEADER_SEARCH_PATHS )
The paths where the gcc compiler and other tools will look for included fi les System paths are prefi xed with $(SDKROOT)
Library Search Paths
( LIBRARY_SEARCH_PATHS )
The folders where the linker will look for libraries
System paths are prefi xed with $(SDKROOT) Framework Search Paths
( FRAMEWORK_SEARCH_PATHS )
Paths for frameworks, used mostly to locate framework headers System paths are prefi xed with
$(SDKROOT) Rez Search Paths ( REZ_SEARCH_PATHS ) Paths for the Rez resource compiler
Always Search User Paths
( ALWAYS_SEARCH_USER_PATHS )
In C, the directives #include “ file.h ” and
#include < file.h > use diff erent search paths to locate the fi le, distinguishing “ user ” from “ system ” headers Making this build setting YES causes both directives to use the same search path
(continued)
Trang 10Precompiled Headers and Prefi x Headers
Precompiled headers are a saved compiler state containing all of the defi nitions defi ned in some source headers It takes quite a bit of time to interpret and construct the type, class, and constants defi ned in a large group of headers, yet most headers do not change at all between builds By saving the compiled form of a commonly used set of headers, the compiler avoids the need to repeat that work for every source fi le in your project
You begin by creating what ’ s called a prefi x header with an extension of .pch This is a source fi le that does nothing but include ( #include ) the headers to which you want access in all of the source
fi les in a target A typical prefi x header is shown in the following code:
#ifdef OBJC
#import < Cocoa/Cocoa.h >
#endif
You can also include other global defi nes or headers that you expect every source fi le to need and you do not expect to change often, if ever Xcode compiles this fi le fi rst, and then automatically
prefi xes it to every source fi le it compiles It is just as if you manually inserted #include
“ MyPrefixHeader.h ” as the fi rst line of every source fi le in your project Most application project templates already include a prefi x header, so look in your project before creating a new one
Prefi x Header ( GCC_PREFIX_HEADER ) The header to include at the beginning of every
source fi le
Precompile Prefi x Header ( GCC_PRECOMPILE_PREFIX_HEADER )
When set to YES , this causes the prefi x header to be precompiled and saved between builds If you use prefi x headers, this should be turned on
C Compiler
The gcc compiler is by far the largest consumer of build settings Most apply to specifi c settings for the gcc compiler You can browse them in the build settings editor under the GNU C/C++
Compiler category Most are self - explanatory You can refer to the gcc man page or the gcc manual
at http://gcc.gnu.org/onlinedocs/ for more in - depth description of the various options and switches
The following table describes some of the more commonly customized C compiler build settings