4.2. Compiling Unix Source Code
Many of the differences between Mac OS X
and other versions of Unix become apparent when you try to build
Unix-based software on Mac OS X. Most Unix-based open source software
uses GNU autoconf or a similar facility, which generates
a configure script that performs a number of
tests of the system--especially of the installed Development
Tools--and finishes by constructing one or more makefiles. After
the configure script has done its job, you run
the make command to first compile, and, if all
goes well, install the resulting binaries.
TIP:
Most tarballs will
include a configure script, so you do not need
to generate it yourself. However, if you retrieve
autoconf-managed source code from a CVS archive,
you will have to run autoconf.sh manually to
generate the configure file.
In most cases, performing the following three
steps is
all that is needed to successfully compile a Unix-based application
on Mac OS X after you have unpacked the tarball and changed to the
top-level source code directory:
./configure
make
make install
WARNING:
Mac OS X web browsers are configured to invoke StuffIt on compressed
archives. So, if you click on a link to a tarball, you may find that
it gets downloaded to your desktop and extracted there. If
you'd prefer to manage the download and extraction
process yourself, Control-click or right-click on the link so you can
specify a download location.
The following sections deal with issues involved in successfully
performing these steps. Determining how to improvise within that
three-step procedure reveals some of the differences between Mac OS X
and other Unix systems.
4.2.2. Host Type
One of the first difficulties you may encounter in running a
configure script is when the script aborts with
an error message stating that the host system cannot be determined.
Strictly speaking, the host type
refers
to the system on which software will run, and the build
type refers to the system on which the software
is being built. It is possible to build software on one system to run
on another system, but to do so requires a cross-compiler. We will
not concern ourselves with cross-compiler issues. Thus, for our
discussion, both the host type and the build (and target) types are
the same:
powerpc-apple-darwinVERSION,
where the VERSION denotes the
particular version of Darwin. In fact, a configure
script detects Mac OS X by the host/build type named
Darwin, since Darwin is the actual operating
system underlying Mac OS X. This can be verified by issuing the
uname -v command, which tells you that
you're running a Darwin kernel, the kernel version,
and when it was last built.
Many configure scripts are designed to determine
the host system, since the resulting makefiles will differ depending
on the type of system for which the software is being built. The
configure script is designed to be used with two
files related to the host type, usually residing in the same
directory as the configure script. These files
are config.guess, which is used to help guess
the host type; and config.sub, which is used to
validate the host type and to put it into a canonical form (such as
CPUTYPE-MANUFACTURER-OS, as
in powerpc-apple-darwin6.0).
Since Mac OS X and Darwin are
relatively new, you may run across source code distributions that
contain older config.* files that
don't work with Mac OS X. You can find out if these
files support Darwin by running the
./configure script. If the script complains
about an unknown host type, you know that you have a set of
config.* files that don't
support Darwin.
In that case, you can replace the config.guess
and config.sub files with the
Apple-supplied, like-named versions residing in
/usr/share/automake-1.6. These replacement files
originate from the FSF and include the code necessary to configure a
source tree for Mac OS X. To copy these
files into the source directory, which contains
the configure script, simply issue the following
commands from within the sources
directory:
cp /usr/share/automake-1.6/config.sub .
cp /usr/share/automake-1.6/config.guess .
4.2.3. Supported Languages
When using the cc
command, which
supports more than one
language, the language is
determined by either the filename suffix or by explicitly specifying
the language using the -x option. Table 4-2 lists some of the more commonly used filename
suffixes and -x arguments supported by
Apple's version of GCC.
Table 4-2. File suffixes recognized by cc
File suffix
|
Language
|
-x argument
|
.c
|
C source code to be preprocessed and compiled
|
c
|
.C, .cc,
.cxx, .cpp
|
C++ source code to be preprocessed and compiled
|
c++
|
.h
|
C header that should neither be compiled nor linked
|
c-header
|
.i
|
C source code that should be compiled but not preprocessed
|
cpp-output
|
.ii
|
Objective-C++ or C++ source code that should be compiled but not
preprocessed
|
c++-cpp-output
|
.m
|
Objective-C source code
|
objective-c
|
.M, .mm
|
Mixed Objective-C++ and Objective-C source code
|
objective-c++
|
.s
|
Assembler source that should be assembled but not preprocessed
|
assembler
|
.S
|
Assembler source to be preprocessed and assembled
|
assembler-with-cpp
|
Although the HFS+ filesystem is case-insensitive, the
cc compile driver recognizes the uppercase C in
a source file. For example, cc foo.C invokes
cc's C++ compiler because the
file extension is an uppercase C, which denotes a C++ source file.
(To cc, it's just a
command-line argument.) So, even though HFS+ will find the same file
whether you type cc foo.c or cc
foo.C, what you enter on the command line makes all the
difference in the world, particularly to cc.
4.2.4. Preprocessing
When you invoke cc without options, it initiates
a sequence of four basic operations, or stages: preprocessing,
compilation, assembly, and linking. In a multifile program, the first
three stages are performed on each individual source code file,
creating an object code file for each source code file. The final
linking stage combines all the object codes that were created by the
first three stages, along with user-specified object code that may
have been compiled earlier into a single executable image file.
Apple's compiler provides two preprocessors. The
default preprocessor for both C and Objective-C is the
precompilation preprocessor
written by
Apple, named cpp-precomp. The standard
GNU
C preprocessor, named cpp, is also available and
is the default for Objective-C++ code.
cpp-precomp supports precompiled header files.
(For more information about cpp-precomp, see
Chapter 5.) cpp-precomp is
faster than cpp. However, some code may not
compile with cpp-precomp. In that case, you
should invoke cpp by instructing
cc not to use cpp-precomp.
For example, to compile the C program myprog.c
using the standard GNU preprocessor, cpp, use
the -no-cpp-precomp
switch as follows:
cc -no-cpp-precomp myprog.c
WARNING:
Earlier versions of the Mac OS X Developer Tools used the
-traditional-cpp switch, but this switch had undesirable
side effects and is deprecated.
Chapter 5 describes precompilation in more detail.
4.2.5. Frameworks
Object-oriented frameworks are critical in Mac OS X. Indeed Cocoa,
the object-oriented toolkit for user interface development, consists
of the Foundation and Application Kit (or AppKit) frameworks for
Objective-C and Java. It is often necessary to let the preprocessor
know where to search for framework header files. You can do this
with the -F option, which is also accepted by
the linker. Thus:
-F directoryname
instructs the preprocessor to search the directory
directoryname for
framework header files. The search begins in
directoryname and, if necessary, continues
in order in the following standard framework directories:
To include a framework object header in Objective-C, use
#import. The format of the
#import preprocessor directive in your Objective-C
code is:
#import <frameworkname/headerfilename.h>
Here, frameworkname is the name of the
framework without the extension, and
headerfilename.h is the
source for the header file.
The -F option is accepted by the preprocessor
and the linker, and is used in either case to specify directories in
which to search for framework header files. (This is similar to the
-I option, which specifies directories to search
for .h files.) By default, the linker searches
the standard directories,
/Local/Library/Frameworks and
/System/Library/Frameworks, for frameworks. The
directory search order can be modified with -F
options. For example:
cc -F dir1 -F dir2 -no-cpp-precomp myprog.c
will result in dir1 being searched first,
followed by dir2, followed by the standard
framework directories. The other flag pertaining to frameworks is
-framework. Inclusion of this flag results
in a search for the specified framework named when linking. Example 4-1 shows "Hello,
World" in Objective-C. Notice that it
#imports the AppKit framework.
Save Example 4-1 as hello.m. To
compile it, use -framework to pass in the
framework name:
cc -framework AppKit -o hello hello.m
The -framework flag is accepted only by the
linker and is used to name a framework. The flag -nostdinc
is used to prohibit the search for header files in any
directory other than those specified via other options, such as
-I. Since strict ANSI-C does not allow many of
the preprocessor constructs used in most software created nowadays,
the preprocessors are designed to allow several nonstandard ANSI-C
constructs by default. Although it is usually undesirable to do so,
you must include the compile driver flags
-trigraphs, -undef, and
-pedantic to enforce strict ANSI-C
standards .
There are also several undocumented features of the compiler. These
include the following cc command-line flags.
- -fpascal-strings
-
A flag that enables the compiler to recognize Pascal strings
- -Wmost
-
A Darwin-specific compiler flag, equivalent to -Wall,
with the exception that it does not turn on
-Wparenthesis
Other compiler flags of particular interest in Mac OS X are related
to the peculiarities of building shared code. For more details, see
Chapter 5.
 |  |  | 4. Compiling Source Code |  | 4.3. Architectural Issues |
Copyright © 2003 O'Reilly & Associates. All rights reserved.
|