home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Book HomeMac OS X for Unix GeeksSearch this book

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.2.1. Macros

You can use a number of predefined macros to detect Apple systems and Mac OS X in particular. For example, _ _APPLE_ _ is a macro that is defined on every Apple gcc-based Mac OS X system, and _ _MACH_ _ is one of several macros specific to Mac OS X. Table 4-1 lists the predefined macros available on Mac OS X.

Table 4-1. Mac OS X C macros

Macro

When defined

_ _OBJC_ _

When the compiler is compiling Objective-C .m files or Objective-C++ .M files. (To override the file extension, use -ObjC or -ObjC++).

_ _ASSEMBLER_ _

When the compiler is compiling .s files.

_ _NATURAL_ALIGNMENT_ _

When compiling for systems that use natural alignment, such as powerpc.

_ _STRICT_BSD_ _

If, and only if, the -bsd flag is specified as an argument to the compiler.

_ _MACH_ _

When compiling for systems that support Mach system calls.

_ _APPLE_ _

When compiling for any Apple system. Currently defined only on Mac OS X systems running Apple's variant of the GNU C compiler. Do not rely on this macro to tell you that you are on Darwin or Mac OS X, since third-party compilers may not define this macro.

_ _APPLE_CC_ _

When compiling for any Apple system. Integer value that corresponds to the (Apple) version of the compiler.

_ _VEC_ _

When AltiVec support was enabled with the -faltivec flag.

WARNING: Do not rely on the presence of the _ _APPLE_ _ macro to determine which compiler features or libraries are supported. Instead, we suggest that you use a package like GNU autoconf to tell you which features the target operating system supports. This approach makes it more likely that your applications can compile out-of-the-box (or with little effort) on operating systems to which you don't have access.

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:

  • /Library/Frameworks (if the -no-cpp-precomp flag is specified)

  • /System/Library/Frameworks

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.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.