Porting Unix
Porting Unix
2008-04-08
Apple Inc. 2002, 2008 Apple Inc. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, mechanical, electronic, photocopying, recording, or otherwise, without prior written permission of Apple Inc., with the following exceptions: Any person is hereby authorized to store documentation on a single computer for personal use only and to print copies of documentation for personal use provided that the documentation contains Apples copyright notice. The Apple logo is a trademark of Apple Inc. Use of the keyboard Apple logo (Option-Shift-K) for commercial purposes without the prior written consent of Apple may constitute trademark infringement and unfair competition in violation of federal and state laws. No licenses, express or implied, are granted with respect to any of the technology described in this document. Apple retains all intellectual property rights associated with the technology described in this document. This document is intended to assist application developers to develop applications only for Apple-labeled computers. Every effort has been made to ensure that the information in this document is accurate. Apple is not responsible for typographical errors. Apple Inc. 1 Infinite Loop Cupertino, CA 95014 408-996-1010 .Mac is a registered service mark of Apple Inc. Apple, the Apple logo, AppleScript, AppleScript Studio, Aqua, Bonjour, Carbon, Cocoa, ColorSync, eMac, FireWire, Mac, Mac OS, Macintosh, Objective-C, Pages, Panther, Quartz, QuickTime, Rosetta, and Xcode are trademarks of Apple Inc., registered in the United States and other countries. Finder is a trademark of Apple Inc. NeXT and OPENSTEP are trademarks of NeXT Software, Inc., registered in the United States and other countries.
Intel and Intel Core are registered trademarks of Intel Corportation or its subsidiaries in the United States and other countries. Java and all Java-based trademarks are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. OpenGL is a registered trademark of Silicon Graphics, Inc. PowerPC and and the PowerPC logo are trademarks of International Business Machines Corporation, used under license therefrom. UNIX is a registered trademark of The Open Group X Window System is a trademark of the Massachusetts Institute of Technology. Simultaneously published in the United States and Canada.
Even though Apple has reviewed this document, APPLE MAKES NO WARRANTY OR REPRESENTATION, EITHER EXPRESS OR IMPLIED, WITH RESPECT TO THIS DOCUMENT, ITS QUALITY, ACCURACY, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. AS A RESULT, THIS DOCUMENT IS PROVIDED AS IS, AND YOU, THE READER, ARE ASSUMING THE ENTIRE RISK AS TO ITS QUALITY AND ACCURACY. IN NO EVENT WILL APPLE BE LIABLE FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES RESULTING FROM ANY DEFECT OR INACCURACY IN THIS DOCUMENT, even if advised of the possibility of such damages. THE WARRANTY AND REMEDIES SET FORTH ABOVE ARE EXCLUSIVE AND IN LIEU OF ALL OTHERS, ORAL OR WRITTEN, EXPRESS OR IMPLIED. No Apple dealer, agent, or employee is authorized to make any modification, extension, or addition to this warranty. Some states do not allow the exclusion or limitation of implied warranties or liability for incidental or consequential damages, so the above limitation or exclusion may not apply to you. This warranty gives you specific legal rights, and you may also have other rights which vary from state to state.
Contents
Introduction
Chapter 1
Overview of Mac OS X 13
The Family Tree 13 BSD 13 Mach 13 NEXTSTEP 13 Earlier Version of the Mac OS 14 Mac OS X and Darwin 14 What Macintosh Users Expect 15 Benefits of Porting to Mac OS X 15 Responsibilities of Porting to Mac OS X 16
Chapter 2
Preparing to Port 17
The Mac OS X Command-Line Environment 17 Installing the Mac OS X Developer Tools 18 Building Makefile Projects With Xcode 19 Windowing Environment Considerations 20 Working with 64-bit Software 20
Chapter 3
3
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
CONTENTS
Chapter 5
Chapter 6
Chapter 7
4
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
CONTENTS
Using Cocoa APIs for File I/O 52 Presenting File Open and Save Dialog Boxes 53 How Mac OS X Device I/O Works 53 File System Organization 54 How Mac OS Networking Works 54 Chapter 8
Chapter 9
Additional Features 61
AppleScript and AppleScript Studio 61 Audio Architecture 61 Boot Sequence 62 Configuration Files 62 Device Drivers 62 The File System 62 File-System Structure and Visibility 63 Supported File-System Types 63 The Kernel 64 Open Directory and the dscl Tool 65 Example: Adding a User From the Command Line 65 Printing (CUPS) 66 Bonjour 66 Scripting Languages 67 Security and Security Services 67 Role-Based Authentication 68
Chapter 10
5
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
CONTENTS
6
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
Overview of Mac OS X 13
Figure 1-1 Darwins relation to Mac OS X 14
Chapter 4
Chapter 5
Chapter 7
Chapter 8
Chapter 9
Additional Features 61
Figure 9-1 XNU personalities 64
7
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
8
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
INTRODUCTION
In-house corporate application developers Commercial UNIX developers Open source developers Open source porters Higher education faculty, staff, and students Science and research developers
INTRODUCTION
If youre a commercial UNIX developer, you are already familiar with other UNIX-based systems and may want to understand the differences between other systems and Mac OS X. You might be interested in porting the GUI from an X11 environment into a native graphics environment using Carbon or Cocoa. You may also have special needs such as direct hardware access, exclusive file access guarantees, and so on. If youre a corporate in-house developer (developing applications for internal use), you probably want to port applications with minimal code divergence. If youre an open source developer, you might want information about how to incorporate new technologies into your software, and may be interested in GUI porting, depending on your level of interest. Alternately, you might be interested only in quickly porting code to a new platform with minimal changes so that you can easily get your changes back into the official code base. If so, you may be more likely to use compatibility shims than to use new APIs. No matter what flavor of developer you are, this book will provide information that is helpful to you and provide pointers to additional documents that may be of interest. Important: This document is not designed for pure Java developers. Mac OS X has a full and robust Java 2 Platform, Standard Edition (J2SE) implementation. If you have a pure Java application already, it should run in Mac OS X. More information on Java development can be found at http://developer.apple.com/documentation/Java/Java.html.
See Also
Developer documentation can be found at Apples developer documentation website at http://developer.apple.com/documentation/. This site contains reference, conceptual, and tutorial material for the many facets of development on Mac OS X. The Mac OS X Developer Tools CD includes a snapshot of the developer
10
INTRODUCTION
documentation, which is installed in /Developer/ADC Reference Library/documentation and can be searched for and viewed in Xcodes doc viewer. They are also accessible from Apples Technical Publications website. The man pages are also included with the Mac OS X Developer Tools. Apple Developer Connection (ADC) hosts a website full of information useful to UNIX developers targeting Mac OS X, http://developer.apple.com/unix. ADC also offers a variety of membership levels to help you in your development. These range from free memberships that give you access to developer software, to paid memberships that provide support incidents as well as the possibility of software seeds. More information on memberships is available at http://developer.apple.com/membership/. Once a year in early Summer, Apple hosts the Worldwide Developers Conference (WWDC) in the San Francisco, California Bay area. This is an extremely valuable resource for developers trying to get an overall picture of Mac OS X as well as specific implementation details of individual technologies. Information on WWDC is available on the ADC website. Apple hosts an extensive array of public mailing lists. These are available for public subscription and searching at http://lists.apple.com. The unix-porting list is highly recommended. The darwin-development and darwinos-users lists also offer much help but less specific to the task of porting. In addition to Apples own resources, many external resources exist. Two recommended websites are OReillys Mac DevCenter, http://www.oreillynet.com/mac/, and Stepwise, at http://www.stepwise.com.
See Also
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
11
INTRODUCTION
12
See Also
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
CHAPTER 1
Overview of Mac OS X
Mac OS X is a modern operating system that combines the power and stability of UNIX-based operating systems with the simplicity and elegance of the Macintosh. For years, power users and developers have recognized the strengths of UNIX and its offshoots. While UNIX-based operating systems are indispensable to developers and power users, consumers have rarely been able to enjoy their benefits because of the perceived complexity. Instead consumers have lived with a generation of desktop computers that could only hope to achieve the strengths that UNIX-based operating systems have had from the beginning. This chapter is for anyone interested in an overview of Mac OS Xits lineage and its open source core, called Darwin. Here you will find background information about Mac OS X and how your application fits in.
BSD
Part of the history of Mac OS X goes back to Berkeley Software Distributions (BSD) UNIX of the late seventies and early eighties. Specifically, it is based in part on BSD 4.4 Lite. On a system level, many of the design decisions are made to align with BSD-style UNIX systems. Most libraries and utilities are from FreeBSD (http://www.freebsd.org/), but some are derived from NetBSD (http://www.netbsd.org/). For future development, Mac OS X has adopted FreeBSD as a reference code base for BSD technology. Work is ongoing to more closely synchronize all BSD tools and libraries with the FreeBSD-stable branch..
Mach
Although Mac OS X must credit BSD for most of the underlying levels of the operating system, Mac OS X also owes a major debt to Mach. The kernel is heavily influenced in its design philosophy by Carnegie Mellons Mach project. The kernel is not a pure microkernel implementation, since the address space is shared with the BSD portion of the kernel and the I/O Kit.
NEXTSTEP
In figuring out what makes Mac OS X tick, it is important to recognize the influences of NEXTSTEP and OPENSTEP in its design. Apples acquisition of NeXT in 1997 was a major key in bringing Mac OS X from the drawing board into reality. Many parts of Mac OS X of interest to UNIX developers are enhancements and
13
CHAPTER 1
Overview of Mac OS X
offshoots of the technology present in NEXTSTEP. From the file system layer to the executable format and from the high-level Cocoa API to the kernel itself, the lineage of Mac OS X as a descendant of NEXTSTEP is evident.
Cocoa Quartz
Java
OpenGL Darwin
Carbon
QuickTime
Darwin is an open source project. With it, you as a developer gain access to the foundation of Mac OS X. Its openness also allows you to submit changes that you think should be reflected in Mac OS X as a whole. Darwin has been released as a separate project that runs on PowerPC-based Macintosh computers as well as x86-compatible computers. Although it could be considered a standalone operating system in its own right, many of the fundamental design decisions of Darwin are governed by its being embedded within Mac OS X. In bringing your applications to the platform, you should target Mac OS X version 10.1.4 (Darwin 5.4) or later. Mac OS X itself is not an Open Source project. As you can see from Figure 1-1 (page 14), there are many parts of Mac OS X that are not included in the Open Source Darwin components. Part of your job while porting is deciding where your application will fit in Mac OS X.
14
CHAPTER 1
Overview of Mac OS X
If you are a developer whose tool is a command-line tool (or has a useful subset that is a command-line tool), you can, of course, simply port your application as a command-line tool or service, which is usually not that complicated. By doing this you gain a small benefit, in that it is now available to Mac OS X users who are familiar with the UNIX command-line environment. You will not be able to market it to Mac OS X users as a whole though, since many users do not even know how to access the command line on their computers. The basic steps in porting a UNIX application to Mac OS X typically include: 1. 2. Port to the command line. Provide a graphical user interface (GUI).
stable long-term customer base good inroad into education powerful developer tools
Bringing UNIX applications to Mac OS X can be very profitable if done correctly. Well-designed Macintosh applications of years past are the standards of today. PhotoShop, Illustrator, and Excel are all applications that first made their name on the Macintosh. Now is the time to win the hearts of Macintosh users with the next great application. In a word, possibly millions of paying customers! Macintosh users are willing to spend their money on great applications because they know that Apple strives to give them a high-quality user environment. Apple developers are known for providing great applications for that environment. For years, Apple has been known for its commitment to education. Mac OS X targets the education market for developers and is an ideal platform for learning for students. With its standards-based technologies as well as home-grown technologies, you have an ideal platform for use in educational application deployment and development. Mac OS X also provides benefits in a development environment. Apple strives for standards first, then it adds that little bit that makes it better on a Mac. As a developer, you have access to many of the development tools and environments that you have on other platforms, like Java, OpenGL, POSIX libraries, and the BSD TCP/IP stack, but you also have built-in benefits like the Apache Web server on every computer, the Cocoa object-oriented development environment, a PDF-based display system (Quartz), Kerberos, QuickTime, a dynamic core audio implementation, and a suite of world-class developer tools. By adding a native Mac OS X front end to your application, you can achieve a cost-effective new deployment platform with minimal additional development effort.
15
CHAPTER 1
Overview of Mac OS X
Mac OS X adds tremendous value both to you and your customers on a standards-based operating system.
A Mac OS X user should never have to resort to the command line to perform any task in an application with a graphical user interface. This is especially important to remember since the BSD user environment may not even be installed on a users system. The libraries and kernel environment are of course there by default, but the tools may not be. If you are making graphical design decisions, you need to become familiar with the Apple Human Interface Guidelines, available from the Apple developer website. These are the standards that Macintosh users expect their applications to live up to. Well-behaved applications from Apple and third-party developers give the Macintosh its reputation as the most usable interface on the planet.
The responsibilities boil down to striving for an excellent product from a users perspective. Mac OS X gives you the tools to make your applications shine.
16
CHAPTER 2
Preparing to Port
A seasoned UNIX developer recognizes that no matter how similar two UNIX-based operating systems may be, there are always details that set one apart from another. This chapter highlights areas to be aware of when compiling your code base for Mac OS X. It notes details about compiler flags that are important to you, and gives insight into how to link different parts of your code in Mac OS X. Many of these topics are covered more extensively in other resources as noted. With few exceptions, this chapter applies to all varieties of UNIX developers. However, there are a few things that are specific to a given audience. These are pointed out as they appear. If you are porting an open source application, you should first check to see if any of the open source port collections have already ported the application to avoid duplicating effort. You should also consider including your port in one of these collections to make it easier for others to take advantage of it. Finally, you should always make your changes available upstream to the original open source project for inclusion in future releases. Some of the Darwin-based open source port collections include:
For more information on these port collections, visit their websites. Important: This information is provided solely for your convenience, and that mention of these projects in no way represents any recommendation or endorsement by Apple. Before you bring the basic port of your code to Mac OS X, make sure that you have the requisite tools for the task. It helps to know what is and isnt available to you by default.
17
CHAPTER 2
Preparing to Port
Once you have a Terminal window open, you can take advantage of a basic selection of common tools, assuming that they are installed. Before using Mac OS X as a development platform, you should make sure that the BSD subsystem is installed. On Mac OS X v10.4, this option is installed by default, but on previous versions, it was not. You can check for this by looking for the BSD package receipt, BSD.pkg, in /Library/Receipts. If this receipt is not present on your system, you must reinstall Mac OS X. When you do, you must customize the installation by checking the BSD Subsystem checkbox. Note: If you have already installed software updates, you cannot simply go back and reinstall over the existing system because of the potential for version conflicts with the software updates. If the BSD subsystem package is not installed, you will have to do an archive and install installation, then reinstall the software updates. For more information, see Mac OS X: About the Archive and Install feature. With the BSD subsystem installed, a look through /bin and /usr/bin should reveal a familiar environment. Welcome home.
Inside /Developer/Tools are many Mac OS X-specific command-line tools. Documentation is provided in the form of man pages.
/usr/bin now contains more command-line tools than were supplied by the BSD package alone, most notably gcc and gdb. /usr/bin/cc defaults to gcc 3 in Mac OS X version 10.2 and later, but gcc 2.95.2
is also available. See Choosing a Default Compiler (page 27) for more information.
18
CHAPTER 2
Preparing to Port
/Developer/Applications contains a wide assortment of graphical tools and utilities. Key among
these are the following: Xcode is a graphical integrated development environment for applications in multiple programming languages. Interface Builder provides a simple way to build complex user interfaces. FileMerge lets you graphically compare and merge files and directories. IORegistryExplorer helps you determine which devices are registered with the I/O KIT. See Device Drivers (page 62) for a discussion of the I/O Kit. MallocDebug analyzes all allocated memory in an application. It can measure the memory allocated since a given point in time and detect memory leaks PackageMaker builds easily distributable Mac OS X packages. Documentation for these tools is available from the Apple Technical Publications website.
4. 5. 6. 7. 8.
19
CHAPTER 2
Preparing to Port
9.
Double-click that new target. You should now see a new window with the build information for this target. This is not the same thing as clicking info. You must double-click the target itself.
10. In the Custom Build Command section of the target inspector, change the field called Directory to point to the directory containing your makefile, and change any other settings as needed. For example, in the Custom Build Settings pane, you could change Build Tool from /usr/bin/gnumake to /usr/bin/bsdmake. More information on the fields is available in Xcode Help. 11. Change the active target to your new target by choosing "Set Active Target" from the Project menu. 12. Add the source files to the project. To do this, first open the disclosure triangle beside the Source folder in the left side of the project window. Next, drag the folder containing the sources from the Finder into that Source folder in Xcode. Tell Xcode not to copy files. Xcode will recursively find all of the files in that folder. Delete anything you dont want listed. 13. When you are ready to build the project, click the Build and Run button in the toolbar, select Build from the Build menu, or just press Command-B. 14. Once the project is built, tell Xcode where to find the executable by choosing New Custom Executable from the Project menu. Choose the path where the executable is located, then add the name of the executable. 15. Run the resulting program by pressing Command-R. This should get you started in bringing your application into the native build environment of Mac OS X.
20
CHAPTER 3
Now that you have the basic pieces in place, it is time to build your application. This section covers some of the more common issues that you may encounter in bringing your UNIX application to Mac OS X. These issues apply largely without regard to what type of development you are doing.
21
CHAPTER 3
Assuming that the build host is architecturally similar to the target architecture and will thus be capable of executing intermediate build products Trying to determine target-processor-specific information at configuration time (by compiling and executing small code snippets) rather than at compile time (using macro tests) or execution time (for example, by using conditional byte swap functions)
Whenever cross-compiling occurs, extra care must be taken to ensure that the target architecture is detected correctly. This is particularly an issue when generating a binary containing object code for more than one architecture. In many cases, binaries containing object code for more than one architecture can be generated simply by running the normal configuration script, then overriding the architecture flags at compile time. For example, you might run
./configure
followed by
make CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc \ -arch i386" LDFLAGS="-syslibroot /Developer/SDKs/MacOSX10.4u.sdk \ -arch ppc -arch i386 -arch ppc -arch i386"
to generate a universal binary (for Intel-based and PowerPC-based Macintosh computers). To generate a 4-way universal binary that includes 64-bit versions, you would add -arch ppc64 and -arch x86_64 to the CFLAGS and LDFLAGS.
22
CHAPTER 3
Note: If you are using an older version of gcc and your makefile passes LDFLAGS to gcc instead of passing them directly to ld, you may need to specify the linker flags as -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk. This tells the compiler to pass the unknown flags to the linker without interpreting them. Do not pass the LDFLAGS in this form to ld, however; ld does not currently support the -Wl syntax. If you need to support an older version of gcc and your makefile passes LDFLAGS to both gcc and ld, you may need to modify it to pass this argument in different forms, depending on which tool is being used. Fortunately, these cases are rare; most makefiles either pass LDFLAGS to gcc or ld, but not both. Newer versions of gcc support -syslibroot directly. If your makefile does not explicitly pass the contents of LDFLAGS to gcc or ld, they may still be passed to one or the other by a make rule. If you are using the standard built-in make rules, the contents of LDFLAGS are passed directly to ld. If in doubt, assume that it is passed to ld. If you get an invalid flag error, you guessed incorrectly. If your makefile uses gcc to run the linker instead of invoking it directly, you must specify a list of target architectures to link when working with universal binary object (.o) files even if you are not using all of the architectures of the object file. If you don't, you will not create a universal binary, and you may also get a linker error. For more information about 64-bit executables, see 64-Bit Transition Guide. However, applications that make configuration-time decisions about the size of data structures will generally fail to build correctly in such an environment (since those sizes may need to be different depending on whether the compiler is executing a ppc pass, a ppc64 pass, or an i386 pass). When this happens, the tool must be configured and compiled for each architecture as separate executables, then glued together manually using lipo. In rare cases, software not written with cross-compilation in mind will make configure-time decisions by executing code on the build host. In these cases, you will have to manually alter either the configuration scripts or the resulting headers to be appropriate for the actual target architecture (rather than the build architecture). In some cases, this can be solved by telling the configure script that you are cross-compiling using the --host, --build, and --target flags. However, this may simply result in defaults for the target platform being inserted, which doesnt really solve the problem. The best fix is to replace configure-time detection of endianness, data type sizes, and so on with compile-time or run-time detection. For example, instead of testing the architecture for endianness to obtain consistent byte order in a file, you should do one of the following:
Use C preprocessor macros like __BIG_ENDIAN__ and __LITTLE_ENDIAN__ to test endianness at compile time. Use functions like htonl, htons, ntohl, and ntohs to guarantee a big-endian representation on any architecture. Extract individual bytes by bitwise masking and shifting (for example, lowbyte=word & 0xff; nextbyte = (word >> 8) & 0xff; and so on).
Similarly, instead of performing elaborate tests to determine whether to use int or long for a 4-byte piece of data, you should simply use a standard sized type such as uint32_t.
23
CHAPTER 3
Note: Not all script execution is incompatible with cross-compiling. A number of open source tools (GTK, for example) use script execution to determine the presence or absence of libraries, determine their versions and locations, and so on. In those cases, you must be certain that the info script associated with the universal binary installation (or the target platform installation if you are strictly cross-compiling) is the one that executes during the configuration process, rather than the info script associated with an installation specific to your host architecture. There are a few other caveats when working with universal binaries:
The library archive utility, ar, cannot work with libraries containing code for more than one architecture (or single-architecture libraries generated with lipo) after ranlib has added a table of contents to them. Thus, if you need to add additional object files to a library, you must keep a separate copy without a TOC. The -M switch to gcc (to output dependency information) is not supported when multiple architectures are specified on the command line. Depending on your makefile, this may require substantial changes to your makefile rules. For autoconf-based configure scripts, the flag --disable-dependency-tracking should solve this problem. For projects using automake, it may be necessary to run automake with the -i flag to disable dependency checks or put no-dependencies in the AUTOMAKE_OPTIONS variable in each Makefile.am file.
If you run into problems building a universal binary for an open source tool, the first thing you should do is to get the latest version of the source code. This does two things:
Ensures that the version of autoconf and automake used to generate the configuration scripts is reasonably current, reducing the likelihood of build failures, execution failures, backwards or forwards compatibility problems, and other idiosyncratic or downright broken behavior. Reduces the likelihood of building a version of an open source tool that contains known security holes or other serious bugs.
Older versions of autoconf do not handle the case where --target, --host, and --build are not handled gracefully. Different versions also behave differently when you specify only one or two of these flags. Thus, you should always specify all three of these options if you are running an autoconf-generated configure script with intent to cross-compile. Some earlier versions of autoconf handle cross-compiling poorly. If your tool contains a configure script generated by an early autoconf, you may be able to significantly improve things by replacing some of the config.* files (and config.guess in particular) with updated copies from the version of autoconf that comes with Mac OS X. This will not always work, however, in which case it may be necessary to actually regenerate the configure script by running autoconf. To do this, simply change into the root directory of the project and run /usr/bin/autoconf. It will automatically detect and use the configure.in file and use it to generate a new configure script. If you get warnings, you should first try a web search for the error message, as someone else may have already run into the problem (possibly on a different tool) and found a solution. If you get errors about missing AC_ macros, you may need to download a copy of libraries on which your tool depends and copy their .m4 autoconf configuration files into /usr/share/autoconf. Alternately, you can add the macros to the file acinclude.m4 in your projects main directory and autoconf should automatically pick up those macros.
24
CHAPTER 3
You may, in some cases, need to rerun automake and/or autoheader if your tool uses them. Be prepared to run into missing AM_ and AH_ macros if you do, however. Because of the added risk of missing macros, this should generally only be done if running autoconf by itself does not correct a build problem. Important: Be sure to make a backup copy of the original scripts, headers, and other generated files (or, ideally, the entire project directory) before running autoheader or automake.
Different makefiles and configure scripts handle command-line overrides in different ways. The most consistent way to force these overrides is to specify them prior to the command. For example:
make CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc"
should generally result in the above being added to CFLAGS during compilation. However, this behavior is not completely consistent across makefiles from different projects. For additional information about autoconf, automake, and autoheader, you can view the autoconf documentation at http://www.gnu.org/software/autoconf/manual/index.html. For additional information on compiler flags for Intel-based Macintosh computers, modifying code to support little-endian CPUs, and other porting concerns, you should read Universal Binary Programming Guidelines, Second Edition, available from the ADC Reference Library.
25
CHAPTER 3
processor architecture byte order file system case sensitivity other file system properties compiler, linker, or toolchain differences availability of application frameworks availability of header files support for a function or feature
Instead it is better to figure out why your code needs to behave differently in Mac OS X, then use conditional compilation techniques that are appropriate for the actual root cause. The misuse of these conditionals often causes problems. For example, if you assume that certain frameworks are present if those macros are defined, you might get compile failures when building a 64-bit executable. If you instead test for the availability of the framework, you might be able to fall back on an alternative mechanism such as X11, or you might skip building the graphical portions of the application entirely. For example, Mac OS X provides preprocessor macros to determine the CPU architecture and byte order. These include:
26
CHAPTER 3
__ppc64__PowerPC (64-bit) __BIG_ENDIAN__Big endian CPU __LITTLE_ENDIAN__Little endian CPU __LP64__The LP64 (64-bit) data model
In addition, using tools like autoconf, you can create arbitrary conditional compilation on nearly any practical feature of the installation, from testing to see if a file exists to seeing if you can successfully compile a piece of code. For example, if a portion of your project requires a particular application framework, you can compile a small test program whose main function calls a function in that framework. If the test program compiles and links successfully, the application framework is present for the specified CPU architecture. You can even use this technique to determine whether to include workarounds for known bugs in Apple or third-party libraries and frameworks, either by testing the versions of those frameworks or by providing a test case that reproduces the bug and checking the results. For example, in Mac OS X, poll(2) does not support device files such as /dev/tty. If you just avoid poll if your code is running on Mac OS X, you are making two assumptions that you should not make:
You are assuming that what you are doing will always be unsupported. Mac OS X is an evolving operating system that adds new features on a regular basis, so this is not necessarily a valid assumption. You are assuming that Mac OS X is the only platform that does not support using poll on device files. While this is probably true for most device files, not all device files support poll in all operating systems, so this is also not necessarily a valid assumption.
A better solution is to use a configuration-time test that tries to use poll on a device file, and if the call fails, disables the use of poll. If using poll provides some significant advantage, it may be better to perform a runtime test early in your application execution, then use poll only if that test succeeds. By testing for support at runtime, your application can use the poll API if is supported by a particular version of any operating system, falling back gracefully if it is not supported. A good rule is to always test for the most specific thing that is guaranteed to meet your requirements. If you need a framework, test for the framework. If you need a library, test for the library. If you need a particular compiler version, test the compiler version. And so on. By doing this, you increase your chances that your application will continue to work correctly without modification in the future.
27
CHAPTER 3
Changes from a two-level to a single-level (flat) namespace. By default, Mac OS X builds libraries and applications with a two-level namespace where references to dynamic libraries are resolved to a definition in a specific dynamic library when the image is built. Use of this flag is generally discouraged, but in some cases, is unavoidable. For more information, see Understanding Two-Level Namespaces (page 29).
-bundle (in LDFLAGS)
Produces a Mach-O bundle format file, which is used for creating loadable plug-ins. See the ld man page for more discussion of this flag.
-bundle_loader executable (in LDFLAGS)
Specifies which executable will load a plug-in. Undefined symbols in that bundle are checked against the specified executable as if it were another dynamic library, thus ensuring that the bundle will actually be loadable without missing symbols.
-framework framework (in LDFLAGS)
Links the executable being built against the listed framework. For example, you might add -framework vecLib to include support for vector math.
-mmacosx-version-min version
Specifies the version of Mac OS X you are targeting. You must target your compile for the oldest version of Mac OS X on which you want to run the executable. In addition, you should install and use the cross-development SDK for that version of Mac OS X. For more information, see SDK Compatibility Guide. More extensive discussion for the compiler in general can be found at http://developer.apple.com/releasenotes/DeveloperTools/.
28
CHAPTER 3
Executable Format
The only executable format that the Mac OS X kernel understands is the Mach-O format. Some bridging tools are provided for classic Macintosh executable formats, but Mach-O is the native format. It is very different from the commonly used Executable and Linking Format (ELF). For more information on Mach-O, see Mac OS X ABI Mach-O File Format Reference.
29
CHAPTER 3
As a general rule, you should avoid creating static libraries (.a) except as a temporary side product of building an application. You must run ranlib on any archive file before you attempt to link against it.
30
CHAPTER 3
Because plugins can be tailored to a particular application, the Mac OS X compiler provides the ability to check these plugins for loadability at compile time. To take advantage of this feature, use the -bundle_loader flag. For example:
gcc -bundle a.o b.o c.o -o mybundle.bundle \ -bundle_loader /Applications/MyApp.app/Contents/MacOS/MyApp
If the compiler finds symbol requests in the plugin that cannot be resolved in the application, you will get a link error. This means that you must use the -l flag to link against any libraries that the plugin requires as though you were building a complete executable. Important: Mac OS X does not support the concept of weak linking as it is found in systems like Linux. If you override one symbol, you must override all of the symbols in that object file. To learn more about how to create and use dynamic libraries, see Dynamic Library Programming Topics.
Bundles
In the Mac OS X file system, some directories store executable code and the software resources related to that code in one discrete package. These packages, known as bundles, come in two varieties: application bundles and frameworks. There are two basic types of bundles that you should be familiar with during the basic porting process: application bundles and frameworks. In particular, you should be aware of how to use frameworks, since you may need to link against the contents of a framework when porting your application.
Application Bundles
Application bundles are special directories that appear in the Finder as a single entity. Having only one item allows a user to double-click it to get the application with all of its supporting resources. If you are building Mac OS X applications, you should make application bundles. Xcode builds them by default if you select one of the application project types. More information on application bundles is available in Bundles vs. Installers (page 57) and in Mac OS X Technology Overview.
Frameworks
A framework is a type of bundle that packages a shared library with the resources that the library requires. Depending on the library, this bundle could include header files, images, and reference documentation. If you are trying to maintain cross-platform compatibility, you may not want to create your own frameworks, but you should be aware of them because you might need to link against them. For example, you might want to link against the Core Foundation framework. Since a framework is just one form of a bundle, you can do this by linking against /System/Library/Frameworks/CoreFoundation.framework with the -framework flag. A more thorough discussion of frameworks is in Mac OS X Technology Overview.
Bundles
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
31
CHAPTER 3
32
Bundles
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
CHAPTER 4
Cocoa
Java
Carbon
Quartz
OpenGL Darwin
QuickTime
If you decide to port your cross-platform application to a native Mac OS X GUI environment, you should carefully consider how best to do this port in a way that is maintainable. For some helpful tips, you should also read (Re)designing for Portability (page 69).
33
CHAPTER 4
Cocoa
Cocoa is an object-oriented framework that incorporates many of Mac OS Xs greatest strengths. Based on the highly-respected OpenStep frameworks, it allows for rapid development and deployment with both its object-oriented design and integration with the Mac OS X development tools. Cocoa is divided into two major parts: Foundation and the Application Kit. Foundation provides the fundamental classes that define data types and collections; it also provides classes to access basic system information like dates and communication ports. The Application Kit builds on that by giving you the classes you need to implement graphical event-driven user interfaces. Cocoa also provides file system abstraction that makes things such as file browsers look like Mac users expect. If you are developing a commercial application, you should use these. If you are developing an in-house application that will largely be used by people familiar with UNIX, the layout may be confusing, so these APIs may not be appropriate. See Presenting File Open and Save Dialog Boxes (page 53) for more information. The native language for Cocoa is Objective-C, which provides object-oriented extensions to standard C and Objective-C++. The Objective-C Programming Language describes the grammar of Objective-C and presents the concepts behind it. Objective-C is supported in gcc 2.95 and 3. Most of the Cocoa API is also accessible through Java. Cocoa is also the basis for AppleScript Studio, an application environment for script-based GUI development. Additional Cocoa information, including sample code, can be found at http://developer.apple.com/cocoa. Cocoa documentation including tutorials is available at http://developer.apple.com/documentation/Cocoa/Cocoa.html.
Rapid development environment Object-oriented framework design Excellent integration with Mac OS X developer tools Very robust feature set Can take advantage of existing C, C++, Objective-C, and Java code Similar level of abstraction to high level toolkits such as Qt, Tcl/Tk, and so on
Cross-platform deployment requires having a separate, non-Cocoa code base for the GUI portion Requires integrating Java, Objective C, or Objective C++ into your code base for the GUI layer Requires knowledge of Java, Objective C, or Objective C++ Very different level of abstraction from raw X11 programming Potential performance penalties if used incorrectly
34
CHAPTER 4
#import <AppKit/AppKit.h> int main(int argc, const char *argv[]) { return NSApplicationMain(argc, argv); }
This gets everything started when the user double-clicks the application icon. A call is then sent to invoke a HelloController object by the NIB, a file that holds interface information. The listings for HelloController.m and HelloController.h follow. Listing 4-2
HelloController.m
#import "HelloController.h" @implementation HelloController - (void)doAbout:(id)sender { NSRunAlertPanel(@"About",@"Welcome to Hello World!",@"OK",NULL,NULL); } - (IBAction)switchMessage:(id)sender { int which=[sender selectedRow]+1; [helloButton setAction:NSSelectorFromString([NSString stringWithFormat:@"%@%d:",@"message",which])]; } - (void)awakeFromNib { [[helloButton window] makeKeyAndOrderFront:self]; } @end
Listing 4-3
HelloController.h
35
CHAPTER 4
The communication between the C, C++, and the Objective-C code is handled as shown in Listing 4-4 (page 36). The header file SayHello.h is shown in Listing 4-5 (page 36). Listing 4-4
SayHello.mm
#import "SayHello.h" #include "FooClass.h" #include <Carbon/Carbon.h> @implementation SayHello - (void)message1:(id)sender { NSRunAlertPanel(@"Regular Obj-C from Obj-C",@"Hello, World! This is a regular old NSRunAlertPanel call in Cocoa!",@"OK",NULL,NULL); } - (void)message2:(id)sender { int howMany; NSString *theAnswer; Foo* myCPlusPlusObj; myCPlusPlusObj=new Foo(); howMany=myCPlusPlusObj->getVariable(); delete myCPlusPlusObj; theAnswer=[NSString stringWithFormat:@"Hello, World! When our C++ object is queried, it tells us that the number is %i!",howMany]; NSRunAlertPanel(@"C++ from Obj-C",theAnswer,@"OK",NULL,NULL); } - (void)message3:(id)sender { Alert(128,NULL); //This calls into Carbon } @end
Listing 4-5
SayHello.h
36
CHAPTER 4
The C++ class wrapped by these Cocoa calls is shown in Listing 4-6 (page 37). The header file, FooClass.h, is shown in Listing 4-7 (page 37). Listing 4-6
FooClass.cpp
Listing 4-7
FooClass.h
class Foo { public: Foo(); int getVariable(); void * objCObject; private: int variable; };
You should be careful when writing code using Cocoa, because the same constructs that make it easy for the developer tend to degrade performance when overused. In particular, heavy use of message passing can result in a sluggish application. The ideal use of Cocoa is as a thin layer on top of an existing application. Such a design gives you not only good performance and ease of GUI design, but also minimizes the amount of divergence between your UNIX code base and your Mac OS X code base.
Java
Mac OS X includes a complete implementation of Java 2 Platform Standard Edition with both the 1.4.x JDK and 1.4.x SDK. Pure Java development in Mac OS works just as it would on other platforms. More information on Java development in Mac OS X can be found online at http://developer.apple.com/java.
Installed by default with Mac OS X Swing elements are displayed with the native Aqua look and feel of Mac OS X Cross-platform deployment
37
CHAPTER 4
Complexities of communicating between two different languages if your code is C-based Limited access to hardware and OS-specific capabilities
Carbon
Carbon is an environment designed to bring existing Mac OS applications to Mac OS X. It can be used to bring an X11 application to a native Mac OS X environment, since the basic drawing primitives are at a similar level of abstraction. Carbon also offers relatively straightforward file I/O with a few enhancements that are unavailable through POSIX APIs, such as aliases (which behave like a cross between a symbolic link and a hard link). Carbon presents the file system differently to the user than UNIX applications do. This is the layout that Mac users are used to seeing, and thus you should use it if possible when developing a commercial application for broad-scale deployment. However, if your users are predominantly UNIX users (for example, if you are an in-house developer in a corporate environment), the use of the Carbon file API may not be appropriate, since volumes appear as they do in the Finder, rather than being organized according to the file system hierarchy.
Well-documented feature set Integration with Mac OS X developer tools Very robust feature set Simple C and C++ integration Similar abstraction level to X11 Procedural design rather than object-oriented
No cross-platform deployment without a separate non-Carbon code base Slightly more effort required to take advantage of native Mac OS X technologies Procedural design rather than object-oriented
In case youre wondering, that isnt a typo. Procedural design in a GUI can be both a benefit and a drawback. Procedural design can be a benefit in terms of being able to easily integrate into any environment, regardless of language. It is also a benefit because it fits many styles of graphical programming well. Procedural design can be a drawback, however, when dealing with more complex GUI designs where it would be more convenient to have the methods more closely tied to the data on which they operate.
38
CHAPTER 4
Cocoa
Java
OpenGL Darwin
Carbon
Quartz
QuickTime
Quartz
Quartz is the graphical system that forms the foundation of the imaging model for Mac OS X. Quartz gives you a standards-based drawing model and output format. Quartz provides both a two-dimensional drawing engine and the Mac OS X windowing environment. Its drawing engine leverages the Portable Document Format (PDF) drawing model to provide professional-strength drawing. The windowing services provide low-level functionality such as window buffering and event handling as well as translucency. Quartz is covered in more detail in Mac OS X Technology Overview and in Apples Quartz website (http://developer.apple.com/quartz/).
PostScript-like drawing features PDF-based Included color management tools Unified print and imaging model
No cross-platform deployment
39
CHAPTER 4
OpenGL
OpenGL is an industry-standard 2D and 3D graphics technology. It provides functionality for rendering, texture mapping, special effects, and other visualization functions. It is a fundamental part of Mac OS X and is implemented on many other platforms. Given its integration into many modern graphics chipsets and video cards, it is of special interest for programs that require intricate graphic manipulation. OpenGLs homepage gives more information on the technology in general at http://www.opengl.org. Apples OpenGL page, at http://developer.apple.com/opengl/, gives more information on how it is integrated into Mac OS X and explains the enhancements that the Mac OS X OpenGL implementation provides.
Cross-platform technology Native Mac OS X integration Included with every installation of Mac OS X Very robust feature set for handling graphics
QuickTime
QuickTime is a powerful multimedia technology for manipulating, enhancing, storing, and delivering graphics, video, and sound. It is a cross-platform technology that provides delivery on Mac OS as well as Windows. More information on the technology can be found at http://developer.apple.com/quicktime/.
Robust feature set for manipulating sound and video Cross-platform development
Note that while QuickTime itself is not supported on UNIX-based systems, the QuickTime file format is supported by various third-party utilities.
40
CHAPTER 5
What Kind of Application Are You Porting? (page 41) How Well Does It Need to Integrate With Mac OS X? (page 42) Does Your Application Require Cross-Platform Functionality? (page 42)
These questions should all be evaluated as you weigh the costs and benefits of each environment. You may already be using a cross-platform toolkit API. If you arent doing so, you may want to port your application to a native API such as Carbon or Cocoa. If you are a commercial developer adding a new graphical user interface to a command-line application and want to take advantage of the greatest strengths of Mac OS X, you will probably want to use the Cocoa API. In some cases, you may want to use a different API for reasons such as cross-platform compatibility. If you decide to use a nonnative API, like X11R6, to provide a user interface for your Mac OS X application, it is important to remember that users and developers with a UNIX background might be perfectly content to just have the application running in Mac OS X. Traditional Macintosh users, however, will pass up an application with a traditional UNIX interface for a more integrated and modern interface. Whether you target a straight port to the Darwin layer or a more robust transformation of your application to take advantage of other Mac OS X technologies (like the Cocoa frameworks) is your decision.
41
CHAPTER 5
Tcl/Tk X11R6 Qt
You can see that Mac OS X includes some standard cross-platform APIs: Java, OpenGL, and QuickTime. There are also commercial and free implementations of some of the traditional UNIX technologies. If you are building a cross-platform application, you should evaluate which platforms you are targeting with your application and determine which API allows you to bring your UNIX-based application to Mac OS X. Table 5-1 (page 43) lists the platforms on which Mac OS X cross-platform technologies run.
42
CHAPTER 5
Platforms of cross-platform technologies Platforms Mac OS X, UNIX-based systems, Windows Mac OS X, UNIX-based systems, Windows Mac OS X, Windows Mac OS X (Native & X11), UNIX-based systems, Windows Mac OS X (Native & X11), UNIX-based systems, Windows Mac OS X (Native & X11), UNIX-based systems, Windows Mac OS X, UNIX-based systems
OpenGL (page 40) Java (page 37) QuickTime (page 40) Qt (page 47) Tcl/Tk (page 47) wxWidgets (page 48) X11R6 (page 46)
Note: Although some of the technologies in Table 5-1 (page 43) are supported in Mac OS 9, support for these technologies in Mac OS 9 is not considered here because the rest of your UNIX code base will not run in Mac OS 9. In the next two chapters, youll find brief descriptions of each of the technologies available to you for your applications graphical user interface.
43
CHAPTER 5
44
CHAPTER 6
45
CHAPTER 6
X11R6
Mac OS X does not include an X11R6 implementation by default. If you are intent on only porting your application without adding any Mac OS X functionality, you can still run X11 on Mac OS X. Along with your application, you should instruct your users on how to install one. The easiest way to get an X11 implementation is to install the Apple X11 implementation. Beginning in Mac OS X v10.3, the X11 package is an optional installation that comes on the install DVD or CD. For older versions of Mac OS X (before v10.4), you can download X11 from http://www.apple.com/downloads/macosx/apple/macosx_updates/x11formacosx.html. Important: Do not install the downloadable version of X11 on Mac OS X v10.4. It will not work. The Apple X11 version compatible with v10.4 is available only on the Mac OS X install DVD. In addition, several other commercial and free alternatives exist. XTools by Tenon Intersystems (http://www.tenon.com) and eXodus from Powerlan USA both provide X11 servers that coexist with Aqua. If you do not need a commercial implementation of X11, XFree86 offers a very robust free X11R6 implementation. The Mac OS X version of XFree86 is an active project with integral support from the XDarwin project. More information on the XDarwin project including tips for installing X11 is available at http://www.xdarwin.org. XFree86 itself can be downloaded from http://xfree86.org/. With an X Window System implementation, you are now free to use toolkits that you are already familiar withfor example, GTK+ or KDE.
The de facto standard in display technology for UNIX-based operating systems Open source implementation is available Somewhat portable to certain embedded systems
Complicated development environment Requires substantial disk space for a full installation Is not native to Mac OS X. This means your application is treated as a second-class citizen to some extent, particularly in the areas of drag-and-drop and system services.
46
X11R6
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
CHAPTER 6
Tcl/Tk
There is a native Aqua version of Tk available at http://tcl.sourceforge.net. With this you can easily add graphical elements to your existing Perl, Python, or Tcl scripts.
Benefits of Tk Development
Cross-platform development environment Easily integrates with Tcl, Perl, and Python scripts Open source implementation is available
Drawbacks of Tk Development
Not supported by default in Mac OS X As with most high-level toolkits, flexibility is limited
Qt
Qt is a C++ toolkit for building graphical user interfaces. It is very popular in the UNIX world, as it is used by the very popular K Desktop Environment, KDE. Trolltech has a native version of Qt, Qt/Mac, available for Mac OS X. If you already have a C++ application or are considering building one, Qt lets you build applications that run natively in Mac OS X as well as Linux and Windows. Information about Qt/Mac is available at http://www.trolltech.com. Qt/Mac does not run on top of X11 in Mac OS X, but the source code is compatible with Qts X11 implementation.
Benefits of Qt Development
Cross-platform development environment Integrates easily with C++ code Robust feature set
Drawbacks in Qt Development
Requires licensing for commercial development As with most high-level toolkits, flexibility is limited
Tcl/Tk
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
47
CHAPTER 6
GTK+/GTKmm
GTK+ and GTKmm are the C and C++ interfaces (respectively) to another toolkit for building graphical user interfaces. It is popular in the Gimp and Gnome development communities. There is a beta native version of the GTK+ 2.x toolkits available for Mac OS X. If you already have a C or C++ application or are considering building one, GTK+ lets you build applications that run natively in Mac OS X as well as Linux and Windows. Information about Gtk-MacOSX (an implementation of the GTK+ 2.x toolkit) is available at http://developer.imendio.com/projects/gtk-macosx. These toolkits do not run on top of X11 in Mac OS X, but are source-codecompatible with the equivalent X11 implementations.
Cross-platform development environment Integrates easily with C/C++ code Robust feature set
LGPL license reverse engineering clause may raise concerns for some commercial developers As with most high-level toolkits, flexibility is limited
wxWidgets
The wxWidgets toolkit is another toolkit for building graphical user interfaces. It is a C++ framework for building native look-and-feel applications in a cross-platform way. It currently supports UNIX/Linux (X11), Windows, and Mac OS X. Support for other platforms is in development. More information about wxWidgets can be found at http://www.wxwidgets.org.
48
GTK+/GTKmm
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
CHAPTER 6
Each provides different capabilities for different purposes. This section points you to existing documentation on the topic and describes common issues that arise when wrapping a command line application with a GUI interface. This section is primarily intended for open source developers, shareware/freeware developers, and in-house UNIX application developers, as these techniques do not offer the same level of functionality that you can get through tighter integration between the GUI and the underlying application.
49
CHAPTER 6
50
CHAPTER 7
Mac OS X offers most of the standard UNIX mechanisms for file and device I/O. There are, however, differences to be aware of when porting your application to Mac OS X from other UNIX-based and UNIX-like platforms. This chapter describes file I/O and device I/O in Mac OS X, including APIs that will enhance the user experience such as the file manager APIs for file access. Note: This document does not cover device driver porting. For information on device driver porting, read Porting Drivers to Mac OS X. If you are a commercial software developer or if your application will be used by end users, you should read this chapter. If you are writing a port of an open source application or an in-house UNIX application, you should read this chapter only if your application already uses or plans to use alternate file APIs for other platforms or if you need to do device I/O.
51
CHAPTER 7
Before moving to a Carbon or Cocoa file browser interface, you should consider what kinds of users are likely to use your application on the Mac platform. Are they mostly experienced in using another UNIX-based platform, or are they largely Mac users? If they are mostly UNIX users, the Mac file dialog may be confusing to them. If they are mostly Mac users, a traditional UNIX file dialog may be equally confusing. You should generally choose which file API to use based on long-term expectations rather than the current user base to avoid problems down the line. Note: Before considering the use of a non-POSIX file API such as those in Carbon or Cocoa, you should read the chapter (Re)designing for Portability (page 69) and consider ways to rearchitect your file accesses to minimize the number of platform-conditional pieces of code, both for readability and for debuggability.
FSClose FSCreateFileUnicode
mkdir
FSCreateDirectoryUnicode Takes the FSRef of the parent directory and the name
Deletes a file or folder (by FSRef). Deletes a file or folder (by FSRef) or delete a single fork of a file.
Note that these functions use FSSpec and FSRef structures rather than file names. The functions FSRefMakePath and FSPathMakeRef convert an FSRef to a path and vice versa. Similarly, FSpMakeFSRef converts an FSSpec to an FSRef.
52
CHAPTER 7
53
CHAPTER 7
Note: For information on porting actual device drivers, read Porting Drivers to Mac OS X.
/Applicationscontains GUI applications /Systemcontains system frameworks and parts of the OS itself /Librarycontains primarily user-installed frameworks /Developercontains the developer tools (if installed) /Userscontains the home directories of local users
In addition, various ports collections are available, and install files in various locations, such as /sw (fink), /usr/local (GNU-Darwin), and /opt/local/ (Darwin Ports). A few directories, including /etc and /tmp are actually symbolic links into /private. You should be careful not to stomp on these symbolic links. Finally, you should be aware that by default, a number of directories are hidden from users when viewing the file system using the Mac OS X GUI. These directories include most of the standard system directories, including /bin, /dev, /etc, /sbin, /tmp, and /usr. These directories still appear and behave in the expected manner when accessed from the command line. For more information on making these visible from GUI applications, see File-System Structure and Visibility (page 63). Mac OS X has different privilege sets for file system access. Users by default have write access to their home directory and certain other directories created in previous versions of Mac OS. Admin users have write access to additional parts of the system, including various application directories and configuration files, without the need to become the root user. Finally, the directories containing the OS itself are read-only except as root.
54
CHAPTER 7
If you need to configure name server settings (or other network settings), you should use the System Configuration framework (described in System Configuration Programming Guidelines and System Configuration Framework Reference). If you need to add static host entries, you should use Directory Services (described in Directory Service Framework Reference, the dscl(1) manual page, and Open Directory and the dscl Tool (page 65) elsewhere in this document).
55
CHAPTER 7
56
CHAPTER 8
Developing an application is only part of the story. You must now get it out there for people to use. Given that this is a UNIX-based operating system, you could just tar and gzip your file. Thats fine if your end users are mostly UNIX users, but this doesnt meet the needs of more general users. To complete the transition, you should package you application like other Mac OS X applications. This chapter walks you through some of those details since they are probably new to you as a UNIX developer. This chapter is important for all non-command-line developers, whether your application is an end-user commercial suite or an open source tool.
57
CHAPTER 8
Packaging Basics
There are two main applications for compressing your application: Disk Utility (or Disk Copy in older versions of Mac OS X) and PackageMaker. Disk Utility allows you to create compressed disk images, while PackageMaker creates packages that can be installed using the Mac OS X installer. The recommended form of application distribution is a compressed disk image. A compressed disk image preserves resource forks that may be present, allows drag-and-drop installation, allows license display, and even allows encryption of data, if required. If your application is a single application bundle, simply put it and any relevant documentation on a disk image with Disk Utility, then compress it and distribute it. If you have an application that requires administrator privileges to install into privileged directories or requires more than a simple drag-and-drop installation, use PackageMaker (/Developer/Applications/PackageMaker) to build installer packages for Apples Installer application. The basics of using Disk Utility to make a disk image are given in the next section. For help using PackageMaker, choose PackageMaker Help from the PackageMaker Help menu.
4.
5. 6. 7. 8. 9.
58
Packaging Basics
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
CHAPTER 8
Figure 8-1
Once you have a disk image, mount it by double-clicking it. You can now copy your files to that mounted image. When you have everything on the image that you want, you should make your image read-only. Again from Disk Utility, perform these steps: 1. Unmount the disk image by dragging the volume to the Trash, clicking the eject button next to the device in a Finder window, or selecting the mounted volume and choosing Eject from the Finders File menu. Choose Convert Image from the Image menu. In the file browser, select the disk image you just modified and click Convert. Choose a location to save the resulting file, change the image format to read-only, and click Convert.
2. 3. 4.
You now have a disk image for your application that is easy to distribute.
Packaging Basics
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
59
CHAPTER 8
# Create an initial disk image (32 megs) hdiutil create -size 32m -fs HFS+ -volname "My Volume" myimg.dmg # Mount the disk image hdiutil attach myimg.dmg # Obtain device information DEVS=$(hdiutil attach myimg.dmg | cut -f 1) DEV=$(echo $DEVS | cut -f 1 -d ' ') # Unmount the disk image hdiutil detach $DEV # Convert the disk image to read-only hdiutil convert myimg.dmg -format UDZO -o myoutputimg.dmg
60
CHAPTER 9
Additional Features
Although many parts of Mac OS X are the same as other UNIX-based operating systems, Mac OS X also includes many things that set it apart. This chapter lists some of the key details that distinguish Mac OS X from most other UNIX-based operating systems. These may not be important for a basic port of a simple application, but the more robust your application and the more tightly it integrates with the underlying operating system, the more important it is to understand the additional functionality provided by the operating system. Most of the information here is covered only as an overview, with references to more detailed documentation where appropriate. This chapter is of interest to all varieties of developers, though different developers will have different interests, depending on the nature of your application.
Audio Architecture
Mac OS X provides much of the audio functionality normally associated with third-party MIDI and audio toolkits. This gives developers a simple platform for developing dynamic audio applications. For end users, it minimizes the configuration that is normally required to get high-end audio applications to work. As a UNIX developer, it means that if you have been looking for a platform to develop a robust audio application on, you now have one. Among the high-level features of the Mac OS X Core Audio subsystem are these:
Native multi-channel audio with plug-in support Native MIDI Audio Hardware Abstraction Layer (HAL) A built-in USB class driver compliant with the USB audio specification A simplified driver model A direct relation with the I/O Kit through the IOAudioDevice class that enables rapid device-driver development
61
CHAPTER 9
Additional Features
If you are developing applications that need access to the audio layer of Mac OS X, you can pursue the extensive resources available at http://developer.apple.com/audio/.
Boot Sequence
The boot sequence in Mac OS X offers a number of advanced features that are not yet common in other UNIX-based and UNIX-like operating systems. These differences are significant enough to warrant their own document: System Startup Programming Topics. In that document, you will learn about legacy startup items (the recommended way to start daemons prior to v10.4), launchd (the recommended way in v10.4 and later), and why you should start your daemons with these mechanisms instead of modifying rc files.
Configuration Files
Often on a UNIX-based system, you find system configuration files in /etc. This is still true in Mac OS X, but configuration information is also found in other places. Networking, printing, and user system configuration details are, by default, regulated by the NetInfo database. Applications usually make use of XML property lists (plists) to hold configuration information. You can view many example property lists by looking in ~/Library/Preferences. If changing a configuration file in /etc does not have your desired effect, then that information is probably regulated by information in the NetInfo database or by an applications property list. For example, users and groups are not handled with files in /etc. To create a user, you instead should use the Accounts preferences pane or NetInfo Manager. NetInfo Manager can also be used to create groups.
Device Drivers
Mac OS X implements an object-oriented programming model for developing device drivers. This technology is called the I/O Kit. It is a collection of system frameworks, libraries, tools, and other resources. This model is different from the model traditionally found on a BSD system. If your code needs to access any devices other than disks, you use the I/O Kit. I/O Kit programming is done using a restricted subset of C++ that omits features unsuitable for use within a multithreaded kernel. By modeling the hardware connected to a Mac OS X system and abstracting common functionality for devices in particular categories, the I/O Kit streamlines the process of device-driver development. I/O Kit information and documentation is available at http://developer.apple.com/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/index.html.
62
Boot Sequence
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
CHAPTER 9
Additional Features
Then restart the Finder either by logging out and back in or by choosing Force Quit from the Apple Menu. There are a couple of other simple ways to view the contents of hidden folders without modifying the default behavior of the Finder itself. You can use the /usr/bin/open command or the Finder Go to Folder command. With open you can open a directory in the Finder, hidden or not, from the shell. For example, open /usr/include opens the hidden folder in a new Finder window. If you are in the Finder and want to see the contents of an invisible folder hierarchy, choose Go to Folder from the Go menu, or just press command-~, and type in the pathname of your desired destination. For information on how to lay out the directory structure of your completed Mac OS X applications, consult Apple Human Interface Guidelines and Mac OS X Technology Overview.
63
CHAPTER 9
Additional Features
The Kernel
The core of any operating system is its kernel. Though Mac OS X shares much of its underlying architecture with BSD, the Mac OS X kernel, known as XNU, differs significantly. XNU is based on the Mach microkernel design, but it also incorporates BSD features. It is not technically a microkernel implementation, but still has many of the benefits of a microkernel, such as Mach interprocess communication mechanisms and a relatively clean API separation between various parts of the kernel. Why is it designed like this? With pure Mach, the core parts of the operating system are user space processes. This gives you flexibility, but also slows things down because of message passing performance between Mach and the layers built on top of it. To regain that performance, BSD functionality has been incorporated in the kernel alongside Mach. The result is that the kernel combines the strengths of Mach with the strengths of BSD. How does this relate to the actual tasks the kernel must accomplish? Figure 9-1 (page 64) illustrates how the kernels different personalities are manifested. Figure 9-1
BSD - Users and permissions - Networking stack - Virtual File System - POSIX
XNU personalities
Mach - Memory management - Messaging - I/O Kit
Memory management Mach messaging and Mach inter process communication (IPC) Device drivers
Manage users and permissions Contain the networking stack Provide a virtual file system Maintain the POSIX compatibility layer
See Inside Kernel Programming Guide for more information on why you would (or wouldnt) want to program in the kernel space, including a discussion on the kernel extension (KEXT) mechanism.
64
The Kernel
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
CHAPTER 9
Additional Features
Through the Users pane of System Preferences Through /Applications/Utilities/Directory (for adding groups) From the command line (see Example: Adding a User From the Command Line (page 65))
You can find more information on NetInfo in the manual pages for netinfo, netinfo, nidump, nicl, nifind, niload, niutil, and nireport on a computer running Mac OS X v10.4 or earlier. NetInfo is no longer supported in Mac OS X v10.5 and later. You should use Directory Service functionality instead. You can find more information on Directory Service in Open Directory Programming Guide, Mac OS X Server Open Directory Administration, and the manual pages DirectoryService, dscl, dsconfigldap, dsexport, dsimport, and dsperfmonitor.
2.
3.
65
CHAPTER 9
Additional Features
4.
5.
6.
Create and set the user home directory. (Despite the name NFSHomeDirectory, this can also be used for a path to a home directory on a local volume.)
dscl / -create /Users/portingunix NFSHomeDirectory /Network/Servers/techno/Users/portingunix
or
dscl / -create /Users/portingunix NFSHomeDirectory /Users/portingunix
7.
or
passwd portingunix
8.
To make that user useful, you might want to add them to the admin group.
dscl / -append /Groups/admin GroupMembership portingunix
This is essentially what System Preferences does when it makes a new user, but the process is presented here so you can see more clearly what is going on behind the scenes with the database. A look through the hierarchies using dscl interactively also helps you understand how the database is organized.
Printing (CUPS)
Mac OS X, beginning in version 10.2, uses the Common UNIX Printing System (CUPS) as the basis of its printing system. CUPS is a free software (open source) print system that is also popular in Linux and UNIX circles. For more information on CUPS, see the Mac OS X Printing website at http://developer.apple.com/printing.
Bonjour
Bonjour is an implementation of the IETF ZeroConf working draft. Bonjour has three basic parts:
66
Printing (CUPS)
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
CHAPTER 9
Additional Features
Service discovery
You can see the first part, IP assignment, simply by plugging two computers together using a crossover cable and setting them up to use DHCP to obtain an address. Upon failing to obtain an address, the computers choose an IP number randomly from within the range reserved for ZeroConf numbers, then ARP to see if anyone has that address already, repeating this process as needed until a free address is found. This means that a relatively large number of machines can choose their own IP numbers without any administration. Multicast DNS is a service that allows you to look up the ZeroConf IP number assigned to a particular machine without an established DNS infrastructure. Your computer sends out a request using IP multicast, asking who responds for a particular host name. The host in question then responds. That host could be a computer, a printer, or any other device that might reasonably exist on an IP-based network. Service discovery is a way to query local machines (using multicast DNS) or a DNS server to see what machines (computers, printers, and so on) support a given service. If you are writing a service, you can register the service using Bonjour. Then anyone else who makes a request sees that your machine supports that service. The service discovery portion of Bonjour is independent of the IP assignment portion. Thus, Bonjour can also be used for service discovery on a more traditional, configured IP network. For more information about Bonjour, see DNS Service Discovery Programming Guide.
Scripting Languages
With Mac OS X, you can run shell scripts in its native sh compatible shell, bash, or the included csh and tcsh. You can also run Ruby, Perl, Python, Tcl, PHP, and other scripts you have developed. In addition, Mac OS X provides an Apple-specific scripting language, AppleScript. Although AppleScript is immensely powerful and can be used to build applications itself, it is designed mainly to communicate with graphical components of the operating system. There are other uses you can find for it, but it is not a replacement for UNIX-style scripting languages. You can use it, though, to put a GUI front end onto your traditional scripts. AppleScript conforms to the Open Scripting Architecture (OSA) language and can be used from the command line through the osascript command. Other languages can be made OSA compliant to enable interaction with the operating system.
Scripting Languages
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
67
CHAPTER 9
Additional Features
Role-Based Authentication
By default, there is no root user password in Mac OS X. This is a deliberate design decision to maximize security and to simplify the user interface. Your applications should not assume that a user needs superuser access to the system. For power users and developers, sudo is provided to run privileged applications in the shell. Privileged applications can also be run by members of the admin group. By default, the admin group is included in the list of sudoers (which can be found in the file /etc/sudoers). You can assign users to the admin group in System Preferences: 1. 2. 3. 4. 5. Click the Users button. Select a user from the list and click Edit User, or make a new user. Click the Password tab. Check Allow user to administer this computer. That user can now use administrative applications as well as sudo in the shell.
Although it is generally considered unsafe practice to log in as the root user, it is mentioned here because the root user is often used to install applications during development. If during development you need to enable the root user for yourself. In Mac OS X prior to version 10.5: 1. 2. 3. 4. Launch /Applications/Utilities/NetInfo Manager. Choose Domain > Security > Authenticate. As prompted, enter your administrator name and password. Now choose Domain > Security > Enable Root User. The first time you do this, you need to select a root password.
In Mac OS X version 10.5 and later: 1. 2. 3. Launch /Applications/Utilities/Directory Utility. Click the lock icon to authenticate yourself. Select Edit > Enable Root User. The first time you do this, you need to select a root password.
Alternatively, you can use sudo passwd root from the shell and set the appropriate root password. Important: Do not assume that an end user of your software can enable the root user. This information is provided to help you in development work only; software you distribute should never require the user to enable the root user.
68
CHAPTER 10
When porting applications to Mac OS X, you might consider making architectural changes to make your port (and future ports) more maintainable. If you are a new developer designing an application that you eventually hope to use on multiple platforms, many of the portability issues described in this chapter apply regardless of the platforms involved.
What is Portability?
There are many different definitions for portability in the context of code design. One definition of portability is limiting yourself to functions specified in a commonly accepted standard such as the Single UNIX Specification (SUS) or the Portable Operating System Interface (POSIX). This is useful for non-GUI software, particularly when moving among UNIX-based and UNIX-like systems, but it does not address graphical user interfaces and does not allow you to take advantage of operating-systemspecific capabilities. The alternative to such limitations is to design your code in a modular fashion so that additional features specific to a given OS can be plugged into your application. Whether you do this with a plug-in interface, a class hierarchy, or simple abstraction, this is the most effective way to allow your software to be easily ported to multiple platforms without sacrificing functionality. There are many different ways to achieve this degree of portability, all of which have valid uses. The goal of this chapter is to describe some of these and to explain when it is appropriate (or inappropriate) to use each one. This should help you avoid some of the common pitfalls when modifying software to support multiple platforms. Of course, the proper time to make such decisions is before you begin writing the first line of code. Since this is not always possible, this chapter will also describe ways to retrofit these concepts into an existing application in the most maintainable manner possible.
What is Portability?
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
69
CHAPTER 10
Youd be surprised how well this single rule fits most situations. Take file access, for example. Say you want to take advantage of the Carbon file API (to get alias support, for example). The code to open, read, and write a file is used in many places in most applications. Therefore, it should be abstracted into its own function and called from those places. What you should generally avoid doing, though, is abstracting the open, read, and write calls individually, then using them inside large loops. This leads to needlessly unreadable code with lots of very small abstraction layer functions. You should instead present an interface that makes sense in the context of your application. For example, if your application performs streaming, you might have the following overall structure:
A function that opens a file A function that reads the next n bytes that returns to a buffer containing the data A function that rewinds the stream by n bytes A function that closes the file
Your open function might return an opaque handle that can be passed around within the core of the application but whose structure is unknown outside the file functions. Similarly, you might have functions that read and write the preferences file using a large data structure, a function to read the header of a file, and so on.
70
CHAPTER 10
For example, X11 applications often have per-window menus, while Mac OS X has per-application menus (with the ability to add or remove menus when a different window is in the foreground). X11 applications tend to have very square features and small, space-efficient buttons, while Mac OS X applications tend to have rounded, large, easier-to-read buttons. Similarly, other operating systems, such as Windows and Classic Mac OS, have different design rules. You must understand the GUI design rules for each computing platform or your application will not be accepted easily on those platforms. For this reason, it is easiest to split your entire user interface into a separate file or directory for X11, then clone that and rewrite it for Carbon or Cocoa when porting to Mac OS X. That way, you can heavily redesign the Mac OS X interface to match what Mac users expect without annoying your UNIX users. A good way to implement this is to write your GUI to operate in a separate thread (or multiple threads, if desired). It can then communicate with the core of the application using pipes or other platform-specific solutions. Another way to implement this is to simply have the GUI call functions in the core of the code. This design is effective when the core of the application is entirely GUI driven, but tends to result in the GUI appearing to wedge if the core of the application can take a long time to complete an operation, and is particularly hard to implement if the core code needs to do something continuously in the background during normal operation. You should consider these issues in your redesign to make your application more palatable to end users.
71
CHAPTER 10
Simplicity
In general, the simpler the plug-in API, the more likely people will use it rather than grafting hacks into other parts of the code. Of course, this becomes a problem if you fail to expose features that are needed for a given plug-in. To solve this problem, design your API based around message passing concepts rather than function calls. That way, you can easily add additional types of messages to the API without modifying the API itself. Of course, if your plug-in API only needs to handle one particular type of communication and you are relatively certain that this will not change, a plug-in architecture based on functions is somewhat easier to use. As with all designs, there are tradeoffs.
Extensibility
Extensibility in API design is a tricky issue. When you are creating a plug-in architecture in general, you can rarely envision the sorts of plug-ins that might eventually be useful. Someone might want plug-ins to add additional functionality that no one had even thought of, much less invented, when you created the architecture
72
CHAPTER 10
You can also use plug-ins to abstract the interface presented by platform-specific services into a more generic form to simplify your application. These designs are more straightforward than architectures intended for adding new functionality; creating plug-in architectures for adding features are beyond the scope of this document. The first step in designing a plug-in API for service abstraction is to choose the level of abstraction at which the application ends and the plug-in begins. If you choose a level that is too close to the application, the plug-ins will contain redundant code. If you choose a level that is too far removed, you will eventually need to interface your application with an environment that does not meet your initial expectations. As a result, the interface code for that module will become excessively complex. In either case, a rewrite is probably in order, which wastes time and resources that could have been saved had you chosen the right level of abstraction to begin with. Choosing the level of abstraction for a plug-in interface can range from straightforward to downright impossible, depending on the application. In general, you should choose to split out the smallest amount of code possible such that the following conditions are met:
No assumptions are made about the data structures of the underlying service. Return values are standardized in a way that meets the needs of your application. The calling convention can be implemented on any system that provides the support necessary for your application to functionthat is, no special features of the underlying service should be implied at the plug-in API level or in your application. The data types passed to and from the plug-in API are one of two kinds: either base types in the programming language of choice, or composites of those base types that are structurally relevant to the application as a whole rather than to the underlying service.
Designing a plug-in API in this fashion may, however, result in substantial duplication of code. In such environments, a nested plug-in approach may be more practical.
Authenticationa generic authentication layer with a generic plug-in for UNIX-based systems and specific plug-ins below to handle platform-specific variations Databasesat the top level, you might have ODBC, JDBC, STET, and SQL, with submodules for other, more specific SQL implementations Printingfor example, you might have a plug-in that handles PostScript printers with narrower plug-ins that override generic assumptions for a particular printer model
In short, whenever you have a group of underlying services that are substantially similar in behavior, but where you want to be able to also support services with dramatically different behavior, a nested plug-in approach is an effective design (unless the differences in behavior at the lowest level are very minimal).
73
CHAPTER 10
getdbcReturns a pointer to a database connection object. The SQL core code treats this as an opaque
type, but this is necessary to allow many database implementations to be used in a multithreaded environment. This information should not leave the SQL core unless the larger design requires connections to multiple databases simultaneously.
opendbOpens a database connection. closedbCloses a database connection. dbquerystringExecutes an SQL query and returns the first result as a string. dblistsongsReturns an array of song IDs that match an SQL query.
It might strike you as odd that this design doesnt specify a generic SQL query call. This is largely a spacetime tradeoff. Implementing a generic query would allow the GUI, for example, to request all of the information about a call in a single request. However, doing so would add a great deal of code for a relatively small time benefit. Since the GUI does not need to refresh frequently, and since the number of queries per second, therefore, tends to be relatively small, it makes sense to design the API to be as simple as possible. If low latency and high bandwidth are required for the specific application, a generic routine is desirable. If you are familiar with SQL, though, you are probably aware that the similarities among SQL implementations end at inserting new tables into the database. Because this is such a small piece of the overall picture for this type of application (one or two lines of code total), it could easily be special-cased in the core code or (preferably) in the generic SQL code. This is one of those cases where you must decide whether the extra 1% of functional abstraction is worth the extra effort involved. In many cases, it is not. If creating tables is more significant, you could create them in one of two ways: by adding a function in the implementation-specific plug-in, or by adding a function in the generic SQL plug-in, using a table for the data types (which could, if desired, reside in the implementation-specific plug-in).
74
CHAPTER 10
To demonstrate the effectiveness of this design, MySQL database support was added to an application that used this exact design in about an hour. With the exception of table creation, no modifications to the generic SQL support routines were required. In summary, proper plug-in design is much like proper abstraction. Code that can be reused should be reused, but the API to the plug-ins should not assume any knowledge of the underlying system.
Architectural Portability
As a good general rule, when writing abstraction layers, plug-in architectures, and so on, architectural portability should be considered. Most existing open source software is already fairly flexible in this regard. However, when dealing with OS-specific code, you may find that consistent support for things like endianness and alignment are not always considered. When you encounter code specific to Mac OS X with architectural dependencies on a particular processor architecture, there are a number of ways to handle the situation. Here are some tips that should help:
Altivec or SSE code should be special-cased with equivalent scalar versions that can be compiled in. This will ensure that it is easy for developers familiar with other chip architectures to understand what is happening and write equivalents for other architectures. Testing of alignment should generally occur at compile time, not configuration time, to avoid unnecessary problems when cross-compiling. Testing of endianness should generally occur at either compile time or execution time, at your option. Executing intermediate build products is a bad idea and should be avoided where possible.
For more detailed information, see Compiling for Multiple CPU Architectures (page 22) and the document Universal Binary Programming Guidelines, Second Edition.
Architectural Portability
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
75
CHAPTER 10
76
Architectural Portability
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
Glossary
ADC See Apple Developer Connection Apple Developer Connection The primary source for technical and business resources and information for anyone developing for Apple's software and hardware platforms anywhere in the world. It includes programs, products, and services and a website filled with up-to-date technical documentation for existing and emerging Apple technologies. The Apple Developer Connection is at http://www.apple.com/developer/. Aqua The graphical user interface for Mac OS X. bom (Bill Of Materials) A file in an installer package used by the Installer to determine which files to install, remove, or upgrade. It contains all the files within a directory, along with information about each file such as the file's permissions, its owner and group, size, its time of last modification, a checksum for each file, and information about hard links. bundle A directory in the file system that stores executable code and the software resources related to that code. Applications, plug-ins, and frameworks are types of bundles. Except for frameworks, bundles are file packages, presented by the Finder as a single file. Carbon An application environment for Mac OS X that features a set of programming interfaces derived from earlier versions of the Mac OS. The Carbon API has been modified to work properly with Mac OS X, especially with the foundation of the operating system, the kernel environment. Carbon applications can run in Mac OS X, Mac OS 9, and all versions of Mac OS 8 later than Mac OS 8.1.
Classic An application environment for Mac OS X that lets you run non-Carbon legacy Mac OS software. It supports programs built for both Power PC and 68K chip architectures and is fully integrated with the Finder and the other application environments. Cocoa An advanced object-oriented development platform for Mac OS X. Cocoa is a set of frameworks with programming interfaces in both Java and Objective-C. It is based on the integration of OPENSTEP, Apple technologies, and Java. Darwin Another name for the core of the Mac OS X operating system. The Darwin kernel is equivalent to the Mac OS X kernel plus the BSD libraries and commands essential to the BSD command-line environment. Darwin is open source technology. .dmg file A Mac OS X disk image file. Finder The system application that acts as the primary user interface for file-system interaction. HFS (Hierarchical File System) The Mac OS Standard file-system format, used to represent a collection of files as a hierarchy of directories (folders), each of which may contain either files or folders themselves. HFS is a two-fork volume format. HFS+ The Mac OS Extended file-system format. This file-system format was introduced as part of Mac OS 8.1, adding support for filenames longer than 31 characters, Unicode representation of file and directory names, and efficient operation on very large disks. HFS+ is a multiple-fork volume format. Mach-O The executable format of Mach object files. This is the default executable format in Mac OS X.
77
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
GLOSSARY
NetInfo The network administrative information database and information retrieval system for Mac OS X. Many Mac OS X services consult the NetInfo database for their configuration information. nib file An XML archive that describes the user interface of applications built with Interface Builder.
.pkg file A Mac OS X Installer file. May be grouped together into a metapackage (.mpkg).
plist See property list. property list A structured, textual representation of data that uses the Extensible Markup Language (XML) as the structuring medium. Elements of a property list represent data of certain types, such as arrays, dictionaries, and strings. Xcode Apples graphical integrated development environment. It is available free with the Mac OS X Developer Tools package. XNU The Mac OS X kernel. The acronym stands for X is Not Unix. XNU combines the functionality of Mach and BSD with the I/O Kit, the driver model for Mac OS X.
78
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
REVISION HISTORY
This table describes the changes to Porting UNIX/Linux Applications to Mac OS X. Date 2008-04-08 2008-02-08 2006-11-07 Notes Fixed minor typographical errors and omissions. Corrected instructions for building with an external Makefile target. Improved shared library and bundle explanation. Updated example from nicl to dscl. Added an explanation of why one should not conditionalize code specifically for Mac OS X. Fixed typographical errors. Corrected external target build instructions. Added hdiutil example and made minor wording improvements. Added an explanation of universal binaries. Added a reference to "Dynamic Library Programming Topics." Added missing step in packaging instructions. Added link to GNU autoconf. Globally changed "Disk Copy" to "Disk Utility." Updated for Mac OS X v10.4. Minor wording changes. Minor wording changes. Updated for Panther
2006-10-03
2005-07-07
79
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.
REVISION HISTORY
80
2008-04-08 | 2002, 2008 Apple Inc. All Rights Reserved.