Tải bản đầy đủ (.pdf) (6 trang)

Lập trình Wrox Professional Xcode 3 cho Mac OS part 48 pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.3 MB, 6 trang )

The fi les in the Input Files list are not passed to the script as parameters, nor are
they piped to it via stdin. They are used by Xcode solely to determine if the
script should be run. It is up to the shell script to read the listed Input Files and
produce all of the fi les promised in the Output Files. If you want to reuse a script
in multiple targets and need a variable list of input or output fi les, defi ne them in
a custom build setting.
BUILD RULES
Build rules defi ne the transformation of source fi les into their compiled results. The compiler phase
uses the target ’ s build rules to determine which compiler should be used to compile each source
fi le. For example, a build rule might specify that all C source fi les (C, C++, and Objective - C) are
compiled using the gcc compiler.
A build rule applies to all the fi les of a specifi c type. The type of a fi le is determined by its extension
or the fi le type assigned to that source fi le. A fi le ’ s type is typically in agreement with the fi lename
extensions, but it doesn ’ t have to be. You can change the fi le type of a
.java source fi le to
sourcecode.cpp . The Compile Sources phase will then apply the sourcecode.cpp rule to that fi le
as if it were a C++ source fi le — probably without much success.
You ’ ll probably never need to alter the build rules in Xcode. However, there are several reasons why
you might want to:
Force Xcode to use an older, newer, or custom compiler.
Add a rule to compile a source type that is not normally compiled by Xcode.
Add a pre - or post - processing script to every compilation.
Defi ne your own transformation.
You can examine and alter the build rules, previously shown in Figure 16 - 4, for a target in the
target ’ s Info window. When it comes time to compile an input fi le, the fi le is tested against each rule
starting from the top of the list. The fi rst rule that matches a particular input fi le is the rule used to
compile that fi le.
Each target has one set of build rules, shared by all of the build phases in that
target. You cannot create different rules for different phases of the same target.
Every set of build rules includes a set of system rules that cannot be edited. The system rules are
always at the bottom of the list. You can add your own custom rules to a target. These custom rules


can only be added to the top of the list and are always evaluated before any of the system rules.
If you defi ne a rule that matches the same type of fi le as a system rule, your custom rule is used
instead. Click and drag the title of a custom rule to reorder it in the list.




Build Rules

359
c16.indd 359c16.indd 359 1/21/10 3:56:17 PM1/21/10 3:56:17 PM
Download at getcoolebook.com
360

CHAPTER 16 TARGETS
Creating Custom Build Rules
To add a new rule, click the + button at
the bottom of the screen. A new, undefi ned
rule is created. Another way to create a
new rule is to modify one of the system
rules; Xcode balks and warns you that you
cannot edit system rules, as shown in
Figure 16 - 13. Click the Make a Copy
button and Xcode duplicates the system as
a new custom rule, which you are free to alter.
Choose the type of fi le that the rule will
process from the Process menu. This can
be one of the Xcode fi le types, as set in the
source fi le ’ s properties, or it can be a fi lename
pattern. To match a fi lename pattern, choose

the Source Files With Names Matching
option at the bottom of the menu and a
fi lename pattern fi eld appears, as shown in
Figure 16 - 14. Enter the fi lename pattern,
such as
*.xml . This fi eld is a globbing
pattern like you would use in the shell; it
is not a regular expression. The pattern is
case - sensitive. By using fi lename patterns,
it is possible to partially override system
rules. For example, the “ C source fi les ”
type encompasses C (
.c ), C++ ( .cpp ), and
Objective - C ( .m ) fi les. By creating a custom rule that matches only *.c fi les, you can redirect plain C
fi les to an alternate compiler while allowing C++ and Objective - C fi les to “ fall through ” and match
the default system rule for compiling any kind of C fi le.
In Xcode 3.0 and 3.1, if you want to use a particular version of the compiler, say
gcc 3.3 instead of gcc 4.0, you should create a custom build rule that overrides
the system build rule for C fi les. In other versions of Xcode the GCC_VERSION
build setting selects the desired compiler. That setting was deprecated in Xcode
3.0, but is supported again in Xcode 3.2 (with many new choices).
If you choose to redefi ne the C compiler by creating a custom build rule, you
must duplicate the rule in every target. Currently, there is no means by which
you can edit the build rules for the entire project; you must create a new build
rule in every target that compiles C source fi les. Modify the System C rule to
quickly create a custom C rule, and then select the desired compiler.
A less refi ned approach is to use the
gcc_select tool to change the default gcc
compiler for your entire system. This will change the default compiler for every
project you build on your system. See man

gcc_select for details.
FIGURE 16 - 13
FIGURE 16 - 14
c16.indd 360c16.indd 360 1/21/10 3:56:27 PM1/21/10 3:56:27 PM
Download at getcoolebook.com
Customizing the Build Rule Compiler
With the fi le type selected, choose the compiler that will process each fi le of this type with the Using
menu. This can be one of the standard Xcode compilers or you can direct compilations to your own
script or tool by choosing the Custom Script item. When you choose a custom script as the compiler
additional fi elds appear, as previously shown in Figure 16 - 14. The fi rst fi eld is the path and fi lename
of the script to execute. The path can be an absolute path or a path relative to the project folder.
The With Output Files control lets you specify what fi les are produced when your compiler is
executed. The naming of output fi les is dynamic and requires build rule variables, described in the
next section.
Build Rule Variables
When your custom script or tool is executed, the following occurs:
The current directory is set to the project ’ s folder.
Environment variables are created that describe the fi le that Xcode wants processed and
where Xcode expects the output fi le, or fi les, to be written.
The rule ’ s script or tool is executed.
Note that no parameters are passed to the script. The script must determine what to process
by examining its environment variables. If you ’ re using an existing compiler or other tool that
expects the input fi le to be in an argument, you will need to write a “ wrapper ” script that
extracts the environment values and passes them to your compiler. The following table lists the
key environment variables passed to a custom build script when it is executed:
ENVIRONMENT VARIABLE DESCRIPTION
INPUT_FILE_PATH The full path, including the fi lename, to the source fi le being
processed.
INPUT_FILE_DIR Just the directory portion of INPUT_FILE_PATH , without the
fi lename.

INPUT_FILE_NAME Just the fi lename portion of INPUT_FILE_PATH , without the
directory.
INPUT_FILE_BASE The base name of the fi le; in other words, the value of INPUT_
FILE_NAME without any fi lename extension.
INPUT_FILE_SUFFIX Just the fi lename extension of INPUT_FILE_NAME .
DERIVED_FILES_DIR The complete path to the directory where Xcode expects the
intermediate fi les to be written. Intermediate fi les are kept
between builds and used to determine if the source fi le needs to
be compiled again by comparing the modifi cation dates of the two.
TARGET_BUILD_DIR The complete path to the target ’ s product directory; in other
words, where the fi nal product of this target is being constructed.



Build Rules

361
c16.indd 361c16.indd 361 1/21/10 3:56:34 PM1/21/10 3:56:34 PM
Download at getcoolebook.com
362

CHAPTER 16 TARGETS
The following is a simple shell script that demonstrates the use of a custom build rule script. In
this example, the project includes XML fi les that defi ne patterns of text. The project contains an
SXL transform fi le that converts an XML fi le into a LEX fi le describing the pattern. The details
are unimportant. The key ingredients are that there is some process that converts the input fi le into
one or more output fi les and the shell ’ s environment variables tell the script where the source and
destinations are.
#!/bin/bash


# Xcode compile script
# Run the input file through the java XSLT transformer
# The KeyPatternToLEX.sxlt file contains a transform that
# will convert the pattern record into LEX syntax.

XSLT = "Source/Transforms/KeyPatternToLEX.sxlt"
IN = "$INPUT_FILE_PATH"
OUT = "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.l"

java org.mycompany.patterns.Transformer "$XSLT" "$IN" > "$OUT"
Writing the Build Rule ’ s Output Files
If the fi les produced by the script go into the target ’ s product, they should be written to the
appropriate location in TARGET_BUILD_DIR .
If the script produces intermediate output fi les, it should write those to the DERIVED_FILES_DIR
directory. Intermediate output fi les are fi les that will be consumed later in this phase. If a compiler
produces one or more intermediate output fi les, Xcode takes those fi les and runs them back through
the build rules. It continues this process until no rule matches the fi les. This example defi ned a
rule that takes an XML fi le and produces a LEX source fi le. When built, Xcode will run the XML
fi le though the custom build script, producing a LEX source fi le. That LEX source fi le will be run
through the rules again. This time, it will match the LEX rule that will compile the LEX fi le into
a C source fi le. That C source fi le is again run through the build rules, this time matching the
System C rule, and ultimately producing an object fi le.
This brings up an interesting conundrum. Xcode has no idea what a custom build script produces
or where. You have to communicate that to the build rule by listing the fi les that the script will
produce. Under the With Output Files section in the build rule, enter the fi lename that will be
produced by the script. You can use any of the environment variables listed in the previous table.
For this example, the output fi le is
$(DERIVED_FILES_DIR)/$(INPUT_FILE_BASE).l , which agrees
with the output fi lename in the script. The syntax for using environment variables in the output fi les
list is $(

VAR_NAME ) , which may be different than the syntax required by your script ’ s interpreter.
If the script produces more than one fi le, say a matched pair of .h and .c fi les, add more fi les by
clicking the + button immediately below the list.
A Build Rule Example
Assume a hypothetical application, called PrimeRules, that needs a precompiled table of prime
numbers. You ’ ve already written a shell script that generates the C source code for a table of
c16.indd 362c16.indd 362 1/21/10 3:56:34 PM1/21/10 3:56:34 PM
Download at getcoolebook.com
prime numbers between 2 and some arbitrary limit. Now you could run that script manually,
capture the output, save it as a fi le, and add that to the project. If the maximum number ever
changed, you ’ d have to repeat the process. The solution is awkward, and the generated C table could
(potentially) be huge.
What you ’ d like is simply to set the maximum prime number somewhere in the project and have
the build automatically generate the table of primes, compile it, and link the results into your
application. One solution is to use a custom build rule:
1. Start with a Command Line project that produces a BSD executable.
2. Add the compilePrimeTables.sh shell script to your project. (Not strictly necessary, but
you ’ d want to check it into source control and make it obvious that it ’ s part of the project.)
The script should not be included in any targets.
3. Add a new build rule to the PrimeRules target, as shown in Figure 16 - 15. The rule takes
*.primetable fi les and uses the compilePrimeTables.sh script to transform them into
C source fi les.
4. Create a new knownprimes.primetable fi le and add it to the project. Edit the fi le; it should
contain nothing except a single number.
5. Add the knownprimes.primetable fi le to the PrimeRules target by dragging it into the
target ’ s Compile Sources build phase.
Build Rules

363
FIGURE 16 - 15

The project is now fi nished, and should look something like the one in Figure 16 - 16.
c16.indd 363c16.indd 363 1/21/10 3:56:35 PM1/21/10 3:56:35 PM
Download at getcoolebook.com
364

CHAPTER 16 TARGETS
FIGURE 16 - 16
FIGURE 16 - 17
When the PrimeRules target is built, the Compile Sources phase runs each of its source items
through the build rules for the target. The main.c fi le gets compiled as you would expect. Because
of your custom build rule, the knownprimes.primetable fi le runs the compilePrimeTables.sh
script, which produces an intermediate .c fi le. The intermediate fi le is run back through the rules
again, and is eventually compiled by the C compiler.
The two fi nal object fi les, main and knownprimes , are linked together to form the fi nished executable.
DEPENDENCIES
A target dependency ensures that the targets required by the current target are built fi rst. Basic targets
produce a product from one, or possibly thousands, of source fi les. These are the atoms from which
you assemble your project ’ s fi nished product. When the product of one target is a source fi le in another
target, it creates a dependency; you communicate that relationship to Xcode using target dependencies.
You must defi ne your target dependencies; Xcode can ’ t do it automatically. You create dependencies
to guarantee that source items produced by other targets are up - to - date before proceeding, as well
as to order and group targets. A target can depend on another target in the same project or in a
different project.
Adding Target Dependencies
To add a dependency to a target, open the
target ’ s Info window. The General tab contains
the Direct Dependencies list. Drag a target,
or targets, from the project ’ s Groups & Files
list into the list. Or, you can click the + button
just below the list and Xcode presents a list

of targets from which to choose, as shown in
Figure 16 - 17. Select one or more targets from
the list and click the Add Target button. To
remove a target, select it in the list and click
the
- button.
c16.indd 364c16.indd 364 1/21/10 3:56:35 PM1/21/10 3:56:35 PM
Download at getcoolebook.com

×