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

Syd logan cross platform development in c++

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

www.dbebooks.com - Free Books & magazines
Cross-Platform
Development
in C++
=
This page intentionally left blank
=
Cross-Platform
Development
in C++
Building Mac OS X, Linux,
and Windows Applications
Syd Logan
Upper Saddle River, NJ • Boston • Indianapolis • San Francisco
New York • Toronto • Montreal • London • Munich • Paris • Madrid
Cape Town • Sydney • Tokyo • Singapore • Mexico City
Many of the designations used by manufacturers and sellers to distinguish their
products are claimed as trademarks. Where those designations appear in this book,
and the publisher was aware of a trademark claim, the designations have been printed
with initial capital letters or in all capitals.
The author and publisher have taken care in the preparation of this book, but make
no expressed or implied warranty of any kind and assume no responsibility for errors
or omissions. No liability is assumed for incidental or consequential damages in
connection with or arising out of the use of the information or programs contained
herein.
The publisher offers excellent discounts on this book when ordered in quantity for
bulk purchases or special sales, which may include electronic versions and/or custom
covers and content particular to your business, training goals, marketing focus, and
branding interests. For more information, please contact:
U.S. Corporate and Government Sales
(800) 382-3419



For sales outside the United States please contact:
International Sales

Visit us on the Web: www.informit.com/title/9780321246424 and
www.crossplatformbook.com
Library of Congress Cataloging-in-Publication Data:
Logan, Syd.
Cross-platform development in C++ : building Mac OS X, Linux, and Windows
applications / Syd Logan.
p. cm.
ISBN 0-321-24642-X (pbk. : alk. paper) 1. Cross-platform software development.
2. C++ (Computer program language) I. Title.
QA76.76.D47L65 2007
005.13’3 dc22
2007036292
Copyright © 2008 Pearson Education, Inc.
All rights reserved. Printed in the United States of America. This publication is
protected by copyright, and permission must be obtained from the publisher prior to
any prohibited reproduction, storage in a retrieval system, or transmission in any
form or by any means, electronic, mechanical, photocopying, recording, or likewise.
For information regarding permissions, write to:
Pearson Education, Inc.
Rights and Contracts Department
501 Boylston Street, Suite 900
Boston, MA 02116
Fax: (617) 671-3447
ISBN-13: 978-0-321-24642-4
ISBN-10: 0-321-24642-X
Text printed in the United States on recycled paper at RR Donnelly in Crawfordsville,

Indiana.
First printing December 2007
Editor-in-Chief
Mark Taub
Acquisitions Editor
Greg Doench
Development Editor
Michael Thurston
Managing Editor
Gina Kanouse
Project Editor
Anne Goebel
Copy Editor
Keith Cline
Indexer
Erika Millen
Proofreader
Kathy Ruiz
Technical Reviewers
Jim Dunn
Amy Fong
Hang Lau
Stephen Morse
Lew Pitcher
Sean Su
Namachivayam
Thirumazshusai
Doug Turner
Roy Yokohama
Publishing

Coordinator
Andrea Bledsoe
Cover Designer
Gary Adair
Composition
Nonie Ratcliff
This book is dedicated to all of the members of Netscape CPD
and Mozilla, from whom I have learned so much.
It was truly an honor to be a part of the team.
=
This page intentionally left blank
Foreword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxiii
About the Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxv
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1
Areas That Can Affect Software Portability . . . . . . . . . . . . . . . . . . . 3
The Role of Abstraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1 Policy and Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Item 1: Make All of Your Platforms a Priority . . . . . . . . . . . . . . . . . 17
Item 2: Code from a Common Codebase . . . . . . . . . . . . . . . . . . . . 22
Platform Factory Implementations . . . . . . . . . . . . . . . . . . . . . . . 29
Implementation Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Platform-Specific ProcessesImpl Classes . . . . . . . . . . . . . . . . . . . 32
Creating the Instance Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . 42
Organizing the Project in CVS or SVN . . . . . . . . . . . . . . . . . . . 45
Makefiles and Building the Code . . . . . . . . . . . . . . . . . . . . . . . . . 49
Item 3: Require Developers to Compile Their Code
with Different Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Item 4: Require Developers to Build Their Code on

Multiple Platforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Item 5: Test Builds on Each Supported Platform . . . . . . . . . . . . . . . 60
Item 6: Pay Attention to Compiler Warnings . . . . . . . . . . . . . . . . . . 61
GNU Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Microsoft Visual C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Contents
vii
=
2 Build System/Toolchain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Item 7: Use Whatever Compiler Makes the Most Sense
for a Platform . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Item 8: Use Native IDEs When Appropriate . . . . . . . . . . . . . . . . . . 67
Item 9: Install and Use Cygwin on Windows . . . . . . . . . . . . . . . . . . 71
Item 10: Use a Cross-Platform Make System . . . . . . . . . . . . . . . . . . 76
Make . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Building on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Autoconf/Automake . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Imake . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Installing on Mac OS X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Installing on Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Using Imake, an Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Imakefiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Building a Complete Program from Multiple Sources . . . . . . . . . 95
Overriding Defaults with site.def . . . . . . . . . . . . . . . . . . . . . . . . 99
Eliminating #ifdefs in Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Files Used by Imake . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Building Projects with Subdirectories . . . . . . . . . . . . . . . . . . . . 108
Building Debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
3 Software Configuration Management . . . . . . . . . . . . . . . . . . 131
Item 11: Use a Cross-Platform Bug Reporting and

Tracking System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Accessibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Ability to Track Platform-Specific Bugs . . . . . . . . . . . . . . . . . . 133
Bugzilla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Item 12: Set Up a Tinderbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Item 13: Use CVS or Subversion to Manage Source Code . . . . . . . 147
Setting Up and Using CVS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Item 14: Use Patch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
An Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
Patch Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Dealing with Rejects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Patch and Cross-Platform Development . . . . . . . . . . . . . . . . . . 163
viii Contents
4 Installation and Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Item 15: Provide Support for Native Installers . . . . . . . . . . . . . . . 165
XPInstall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
Platform Installs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
5 Operating System Interfaces and Libraries . . . . . . . . . . . . . . . 221
Item 16: Use Standards-Based APIs (For Example, POSIX) . . . . . . 222
POSIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
Support for POSIX, SVID, XPG, and BSD . . . . . . . . . . . . . . . 226
Using Standards Support in GCC . . . . . . . . . . . . . . . . . . . . . . . 227
Microsoft Runtime Library Support for POSIX . . . . . . . . . . . . 231
Using GCC on Microsoft Windows . . . . . . . . . . . . . . . . . . . . . 234
Deciding Which Standards to Support . . . . . . . . . . . . . . . . . . . 240
Item 17: Consider Using a Platform Abstraction Library
Such as NSPR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
Why NSPR? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
NSPR Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249

Additional NSPR Functionality . . . . . . . . . . . . . . . . . . . . . . . . 260
6 Miscellaneous Portability Topics . . . . . . . . . . . . . . . . . . . . . . . 273
Item 18: Take Care When Using Floating Point . . . . . . . . . . . . . . . 274
Don’t Serialize Floating-Point Values as Binary . . . . . . . . . . . . 276
Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
Item 19: Be Explicit Regarding the Sign of Char Types . . . . . . . . . 278
Item 20: Avoid the Serialization of Binary Data . . . . . . . . . . . . . . 280
Item 21: Avoid Problems Related to the Size and
Organization of Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
Size of Integer Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
NSPR and Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Sizes and Efficiency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
Integer Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Struct Alignment and Ordering . . . . . . . . . . . . . . . . . . . . . . . . . 299
7 User Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
Item 22: Separate the User Interface from the Model . . . . . . . . . . 304
Separating the User Interface and Application Logic
with Model/View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
Contents ix
Using Publish/Subscribe to Communicate between
the View and the Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 322
Item 23: Develop a Cross-Platform User Interface Strategy . . . . . . 323
Issues Affecting Portable Cross-Platform GUI
Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 323
Choosing a GUI Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
8 wxWidgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
wxWidgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Licensing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
Installing wxWidgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332

A Simple Example: Hello wxWidgets . . . . . . . . . . . . . . . . . . . . 335
Creating the Application User Interface . . . . . . . . . . . . . . . . . . 337
Building wxWidgets Applications . . . . . . . . . . . . . . . . . . . . . . . 345
Controls and Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
Container Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363
Dialogs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
Composite Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Internationalization and Localization . . . . . . . . . . . . . . . . . . . . 410
9 Developing a Cross-Platform GUI Toolkit in C++ . . . . . . . . . . . 427
What is XUL? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
DHTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
Scripting Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
The Document Object Model . . . . . . . . . . . . . . . . . . . . . . . . . . 434
Style Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
XUL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
Windows and Dialogs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
Boxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
Toolbars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440
Menus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Controls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Other Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442
Programming with XUL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442
Adding Logic to the UI with JavaScript . . . . . . . . . . . . . . . . . . 443
x Contents
Interfacing JavaScript and C/C++ Code with XPCOM
and XPConnect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444
Trixul . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446
Widget Support in Trixul . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
Basic Operation of Trixul . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448

Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
Implementation Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452
Creating Widget Implementation Objects . . . . . . . . . . . . . . . . . 459
Widget Factories . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
Application Main Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
Steps Taken by Trixul to Create a User Interface . . . . . . . . . . . . 471
Documents, Elements, and the DOM . . . . . . . . . . . . . . . . . . . . 472
Widget Creation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475
Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
Scrolled Windows and Layout . . . . . . . . . . . . . . . . . . . . . . . . . 484
Integration with JavaScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485
Integrating with C++ Components . . . . . . . . . . . . . . . . . . . . . . 496
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Contents xi
This page intentionally left blank
As the Hypertext Markup Language / Extensible Markup Language /
Cascading Style Sheets (HTML/XML/CSS) parsing and rendering engine
for the Firefox, Mozilla, and Netscape browsers, Gecko is one of the most
widely deployed cross-platform rendering engines in the world.
As both a Netscape engineer and later as the development manager of
the Mozilla Gecko team, I had the privilege to work on the Gecko engine
from its inception.
Gecko was born out of the desire to create a cross-platform, small-
footprint, fast, state-of-the-art, embeddable Web browsing engine that
would leapfrog our competition in the “browser wars.” It had become
painfully apparent that it was too difficult to add full CSS2, CSS3, and
XML Web standards support to the lumbering Netscape 4.x engine. The
idea was to start from scratch using only a few libraries from the original
engine. Early in the Gecko project, there were discussions about using Java
rather than C++ to leverage Java’s cross-platform capabilities. It was

ultimately decided that C++, along with special development processes,
tools, and design techniques, would yield the best solution. Many of those
processes, tools, and design techniques are described as best practices
throughout this book.
Before coming to Netscape, I worked at several companies that produce
cross-platform software. However, the Mozilla project took it to a whole
other level. We utilized and developed software architectures, tools, and
processes that enabled cross-platform development on a wide scale.
My first task was to port Gecko from Microsoft Windows to
Motif/Xlib. As anyone who has written cross-platform software knows, the
early ports are the most challenging. That’s where you discover just how
portable your software really is. Even though Gecko was designed from the
beginning to be portable, small differences between platforms and compilers
Foreword
=
xiii
came back to bite us. This is why it’s so important to have a continuous
build system such as the Mozilla Tinderbox that verifies every source code
check-in for portability and a software development process that requires
engineers to verify their new code on at least two platforms before they
check into the source code repository.
As the Gecko engine development gained momentum, the decision was
made to re-create the Netscape Communicator user interface experience on
top of it. This would require a cross-platform user interface solution
because Netscape Communicator worked on multiple platforms with
diverse graphical user interface environments. I was given the opportunity
to develop a strategy to solve the thorny cross-platform user interface
problem. I authored a document that described how to achieve a cross-
platform user interface by combining an XML meta description of the user
interface elements and JavaScript as control/event logic within the Gecko

rendering engine. This document was the seed document for what later
became the XUL (XML User Interface Language) language. Later, the
Firefox developers took advantage of XUL and the Gecko engine to build a
small, fast, cross-platform, Web browser that has become wildly popular.
Chapter 9 describes how you can also build on top of XUL to create your
own cross-platform user interfaces.
As an original member of the W3C SVG (Scalable Vector Graphics)
working group, I am particularly excited to see that Gecko continues to
evolve and solve additional cross-platform challenges. The recent addition
of SVG native support marks yet another chapter in Gecko’s portability
success.
The information Syd Logan is presenting here is the collective insight of
the myriad engineers who ironed out the special problems associated with
creating cross-platform production software. Although it is written with
C++ in mind, many of the techniques can be adapted to non-C++ software
projects, too. I hope you will be able to use some of the tools, techniques,
and processes described in these pages to avoid some of the pitfalls of cross-
platform development and make your project a huge success.
—Kevin McCluskey
xiv Foreword
During the ten or so years of my career prior to joining Netscape in 1998, I
had the good fortune to work on a wide variety of projects, on an equally
diverse set of platforms. I worked on an embedded kernel of my own design
for a somewhat obscure CPU (the TMS34020). I obtained experience in
Windows kernel development, writing file systems drivers for the Windows
NT and Windows 98 kernels, to support the development of a Network File
System (NFS) client. In user space, I mostly specialized in user interface
development, initially developing Motif (Z-Mail) and OpenWindows
applications for UNIX, eventually getting exposure to Win32 and the
Microsoft Foundation Classes (MFC) toolkit on the Windows platform. I

even had the chance to write code for the Classic Mac OS to support a
project that would be shipped by Apple, using the Mac Toolbox application
programming interface (API). All of this code was written in the C language,
and all of it was highly nonportable, written only with a concern for the job,
and platform, at hand.
But then I joined Netscape, as a UNIX expert of sorts. Initially, I was
assigned the task of working on bugs in the 4.x Netscape browser, specifically
handling defects filed against a port of the browser to IBM’s Advanced
Interactive eXecutive (AIX) platform. Netscape had a contract with IBM to
ensure that bugs filed against the AIX version of the Netscape browser, or
bugs that IBM considered important, were fixed in a timely fashion, and this
contract funded my hiring. Similar deals were cut with SGI, Hewlett-Packard,
and Sun, and perhaps others, and these deals funded additional Netscape
staff. Two or three of us were assigned to deal with AIX, specifically.
During this time, portability had not yet been perfected at Netscape.
Although much of the codebase of Netscape was portable, the project did
not have a unified build system, and the user interface code was completely
Preface
=
xv
platform specific. Many bugs had a decidedly platform-specific nature to
them (hence the need to have separate teams to support individual plat-
forms). Code that worked flawlessly on the Windows version of Netscape
ran horribly on less well-supported platforms. Not all platforms had the
same set of features, and features varied from platform to platform.
Within a year of joining Netscape and fixing AIX bugs, I somehow
earned my way onto the Netscape Instant Messenger team, and worked on
the new codebase based on the open source Mozilla platform. This team,
which consisted of three engineers, was tasked with porting the AOL Instant
Messenger client to the Netscape browser. The Netscape IM team was

hastily formed right after AOL acquired Netscape, to try to bring AOL-
based functionality into the application. (The other major AOL property
integrated into Netscape was support for AOL Mail.)
The new Netscape client, in development at that time, was, as men-
tioned previously, based on the open source codebase named Mozilla. This
codebase, at the time, was largely the product of Netscape engineers located
in offices located in San Diego, and Mountain View, but contributions from
the open source community were on the rise. (I refer to the project as
Netscape/Mozilla in the remainder of this Preface.)
Netscape was in fierce competition with Microsoft for the browser
market at this time, which meant the browser of course had to work well,
and ship on time on the Windows platform. Netscape also generated
significant advertising revenue through the Netscape portal, and clicks there
were highest when a new version of the browser was released, and tens of
millions of users visited the portal to download a fresh copy of Netscape.
Supporting Netscape not only on Windows but also on Mac OS and Linux
helped keep the number of visits high and generate revenue. So, Linux and
Mac OS were treated as equals with Windows within the Netscape culture,
not only because it was the morally right thing to do (as many of us
believed), but also because every visit to the Netscape portal was important
to the bottom line of the company.
Netscape/Mozilla was a complete departure from anything that I had
ever seen or worked on before. First of all, this new version of Netscape was
not just a browser, it was a platform, capable of hosting applications. (The
primary examples shipped with Netscape were AIM, the Mail/News client,
a WYSIWYG HTML editor named Composer, the Chatzilla IRC client, and
the browser itself. Extensions, such as those available for Firefox today, are
closely related.) Instead of building the graphical user interface (GUI) for
these applications in C or C++, using APIs provided by a native platform
xvi Preface

GUI toolkit such as MFC or Gtk+, Netscape/Mozilla-developed technolo-
gies were used instead. Static Extensible Markup Language (XML) files
were used to describe the layout of the user interface, much like HTML is
used to describe the layout of a Web page. The XML dialect developed for
this purpose was called XML User Interface Language (XUL). JavaScript
code, linked to the XML elements via attributes much like JavaScript is
linked to HTML elements in a Web page, was used to respond to menu item
selections and button clicks. To build an application for Netscape/Mozilla,
all one needed was this combination of XML and JavaScript; and because
both JavaScript and XML are intrinsically portable, so were the user
interfaces that were designed using these technologies. When JavaScript
wasn’t enough to do the job (as was the case for any real applications, like
those shipped with Netscape and Mozilla), JavaScript code could call C++
functions that provided the guts of the application, housed in shared
libraries. These shared libraries, or components, were directly supported in
the Netscape/Mozilla architecture via two technologies: XPConnect and
XPCOM. These technologies allowed component developers to define
platform-agnostic interfaces using an Interface Description Language (IDL).
Using XPCOM and XPConnect, JavaScript code could query for the
existence of a component, and from there, query for a specific interface. If
all was good, the JavaScript code was handed an object that it could call just
like any other object, except the object was written in C++, and was capable
of doing things that JavaScript programmers could only dream of. The
interfaces, by their nature, were highly platform agnostic.
The impact of the work done to support portability in the
Netscape/Mozilla architecture was not, quite frankly, immediately apparent
to me. But, over time, I came to appreciate the power of such an approach.
The positive effects of the decisions of those who came up with the
architecture are indisputable; during its heyday, Netscape was shipping tens
of millions of browsers to users, not just for Windows, Mac, and Linux, but

for SunOS, AIX, HP-UX, SGI Irix, and a host of other UNIX-based
platforms. The “tier-1” platforms (Mac OS, Linux, and Windows) literally
shipped at the same time. Each of these ports had, for the most part, the
same feature set, and mostly shared the same set of bugs and quirks. To
achieve portability at such a grand scale required a very special architecture,
and it is one of the goals of this book to give you a good understanding (if
not an appreciation) for how the Netscape/Mozilla architecture directly
impacted the portability of the codebase.
Preface xvii
However, it was not just the architecture of Netscape/Mozilla that made
the browser and related applications (AIM, Mail, Composer) portable. To
pull this sort of thing off, one needs not only a solid architecture, but also a
culture of policies and procedures that put cross-platform development high
on their lists of priorities—as well as large doses of discipline to ensure these
best practices were followed. Tools, such as Tinderbox and Bugzilla, both of
which are described in this book, were invested in heavily by Netscape and
Mozilla, and the investment paid off in spades. Engineers were forced to
consider other platforms, not just their own, and a regression found during
daily testing on just one platform could halt development on all platforms,
not just the one affected, because Netscape and Mozilla realized that the
only true way to achieve portability was to deal with the issues in the here
and now. A good chunk of this book steps away from the code, and
describes these best practices, because no matter how good your architec-
ture is in supporting cross-platform, you have to work all the platforms you
plan to support with the level of care and devotion to detail if they are going
to make it to the finish line with the same levels of quality.
Similar to the way that the programs we write are made up of data
structures and algorithms, portability, in my opinion, consists largely of
architecture and process, and this conviction is at the foundation of the
book that you now hold in your hands.

How This Book Is Organized
This book is organized as a series of themed chapters. Most of these
chapters consist of a set of items, with each item covering a specific topic
supporting the chapter’s overall theme. Early in the book, you will find
sections that contain items presenting best practices that must be communi-
cated to the entire development organization, including management,
development, and testing. Later chapters cover software-engineering topics
that management should be aware of, but these chapters have been written
primarily for readers who will be implementing the code. In all, there are
23 items presented in these initial chapters.
The implementation of a user interface is a major concern in the
development of cross-platform desktop applications. Item 23 serves to
introduce the topic. The final two chapters of the book are therefore
devoted to cross-platform GUI-related topics. The first of these chapters
xviii Preface
provides a comprehensive introduction and tutorial to the wxWidgets cross-
platform GUI toolkit. After reading my introduction to wxWidgets, you
may want to check out Prentice Hall’s detailed treatment on the subject,
Cross-Platform GUI Programming with wxWidgets, by Julian Smart, et al.
wxWidgets is not the only cross-platform GUI toolkit available for use in
your projects. Another capable, and very popular cross-platform GUI
toolkit, Qt, is not covered in this book. However, if you are interested in Qt,
a few books are currently available that cover the subject in great detail,
perhaps most notably C++ GUI Programming with Qt 4, by Jasmin
Blanchette and Mark Summerfield, also published by Prentice Hall (see also
their Qt 3-specific book).
The last chapter of this book, Chapter 9, “Developing a Cross-Platform
GUI Toolkit in C++,” starts with an introduction to the cross-platform GUI
toolkit, XPToolkit, which is a major component of Netscape and Mozilla’s
cross-platform browser suite. It then goes on to detail the implementation of

a toolkit I created especially for this book, Trixul. Trixul has many of the
same attributes that made up the Netscape/Mozilla XPToolkit we used at
Netscape to construct cross-platform GUIs. Both XPToolkit and Trixul, for
example, allow you to describe the user interface of an application in XML
and JavaScript, both support a component-based model that allows the user
interface to call into shared libraries written in C or C++, and both are
highly portable. However, there are two major differences between Trixul
and the Mozilla offering. First, Trixul is a desktop GUI toolkit, whereas
XPToolkit applications execute within the context of a Web browser only.
Second, the overall design of Trixul is (I think) much simpler than
XPToolkit, which (I am certain) allowed me to do a much better job of
describing both the architecture of the toolkit, and the concepts behind its
design, than I otherwise would have been able to do. Although I don’t really
expect that you will want to design a custom cross-platform GUI toolkit for
your project, there is much to be learned from taking a look at how Trixul
was designed and implemented.
The chapters, for the most part, have been written such that they can be
read in any order. If you are in technical management, I recommend that
you read the following chapters carefully:
■ Chapter 1, “Policy and Management”
■ Chapter 2, “Build System/Toolchain”
■ Chapter 3, “Software Configuration Management”
Preface xix
Technical managers who are so inclined should consider at least scanning
through the following sections:
■ Chapter 4, “Installation and Deployment”
■ Chapter 5, “Operating System Interfaces and Libraries”
■ Chapter 6, “Miscellaneous Portability Topics”
■ Chapter 7, “User Interface”
Developers should plan to read the entire book, although you might

want to invert the recommendations made here for technical managers,
and skim what they are supposed to read carefully, and read carefully what
they are supposed to skim. If your focus is user interface development, I
recommend reading Items 22 and 23, and Chapter 8, “wxWidgets.” If you
are interested in GUI toolkit internals, or plan to help out with the develop-
ment of Trixul (described in the following section), you will definitely want
to read Chapter 9, “Developing a Cross-Platform GUI Toolkit in C++.”
A Word about Trixul
Trixul is an open source project that I put together specifically to aid me in
the writing of this book. In part, I had the same intentions of the original
authors of the Gtk+, to learn by doing. However, the more relevant goal
behind Trixul was to develop a simple, cross-platform toolkit, the architec-
ture and design of which could be easily described in fewer than 100 pages,
and understood by mere mortals without the need to read huge globs of
code. The design is heavily inspired by Netscape/Mozilla (the Document
Object Model [DOM], the Gecko layout engine, XUL, XPConnect, and
XPCOM are all Netscape/Mozilla technologies that have analogs in Trixul);
and although the details differ, I am certain that much of what you learn
about Trixul’s architecture will help you to understand Netscape/Mozilla.
Not everyone will want, or need, to write his own GUI toolkit, but Netscape
did, and so did America Online (a not-so-portable effort named Boxely was
developed in the years following Netscape’s demise), and perhaps it makes
sense for your company, too. The story of Mozilla/Netscape’s portability is
not at all complete without a discussion of the way in which the user
interface problem was solved, and Trixul is, in my opinion, the best way to
get the idea across in a reasonable number of pages.
However, Trixul isn’t just for learning. It is my sincere hope that Trixul
will take on a life of its own as a viable, next-generation desktop GUI
toolkit. The project, at the time of writing this book, is in its infancy. If you
xx Preface

like what you read about Trixul and are interested in contributing to its
development, or work on a port, I certainly want to hear from you. You
can learn more by visiting www.trixul.com or the project page at
/>References
The following is a short list of books that are either mentioned directly in
the text, or have influenced in some way the content of this book:
Andrei Alexandrescu, Modern C++ Design: Generic Programming
and Design Patterns Applied (Reading, MA: Addison-Wesley, 2001).
Jasmine Blanchette and Mark Summerfield, C++ GUI Programming
with Qt 3 (Upper Saddle River, NJ: Prentice Hall, 2004).
Randal E. Bryant and David O’Hallaron, Computer Systems A
Programmer’s Perspective (Upper Saddle River, NJ: Prentice Hall,
2003).
David R. Butenhof, Programming with POSIX Threads (Upper
Saddle River, NJ: Prentice Hall, 1997).
Paul Dubois, Software Portability with imake (Sebastopol, CA:
O’Reilly Media, Inc., 1996).
Erich Gamma, et al., Design Patterns (Reading, MA: Addison-
Wesley, 1995).
Simson Garfinkel and Michael K. Mahoney, Building Cocoa
Applications: A Step-by-Step Guide (Sebastopol, CA: O’Reilly
Media, Inc., 2002).
Ian Griffiths, et al., .NET Windows Forms in a Nutshell (Sebastopol,
CA: O’Reilly Media, Inc., 2003).
Greg Lehey, Porting UNIX Software (Sebastopol, CA: O’Reilly
Media, Inc., 1995).
Syd Logan, Developing Gtk+ Applications in C (Upper Saddle River,
NJ: Prentice Hall, 2001).
Scott Meyers, Effective C++ (Reading, MA: Addison-Wesley, 2005).
Preface xxi

Andrew Oram and Steve Talbot, Managing Projects with make
(Sebastopol, CA: O’Reilly Media, Inc., 1993).
Eric S. Raymond, The Art of UNIX Programming (Reading, MA:
Addison-Wesley, 2003).
Julian Smart, et al., Cross-Platform GUI Programming with
wxWidgets (Upper Saddle River, NJ: Prentice Hall, 2006).
Bjarne Stroustrup, The C++ Programming Language (Reading, MA:
Addison-Wesley, 2000).
xxii Preface
Writing a book is, as you might imagine, very much a solitary effort.
However, producing a book is, in reality, anything but a solo effort—it takes
the talent, the time, and the dedication of a great many people to get a book
from concept to completion. In that spirit, I would like to thank the
following people for their role in helping me to get this book out the door.
First of all, thanks to Greg Doench of Prentice Hall for believing in me,
and for giving me the chance to once again put my thoughts down on paper.
Michelle Housley, his assistant, provided much-needed support along the
way. I’d also like to thank the team at Pearson Education who helped turn
my manuscript into its final form, including Keith Kline who did much of
the copyediting, Anne Goebel, and Gina Kanouse. I am particularly grateful
to Anne for her willingness to work with me through numerous “minor”
changes I requested during the final review process. There is no doubt in my
mind that these requests caused her much extra work (not to mention pain
upon receiving each new e-mail from me with the “latest corrections”).
Regardless, she carefully considered and applied each of my requests,
flawlessly, and without complaint. For this, she deserves an extra dose of
“thank yous.” As is standard practice, all errors not caught by them
remain my responsibility alone. (On that note, please visit www.
crossplatformbook.com for errata related to this edition of the book.)
Next, I’d like to thank the reviewers of this book, many of whom

worked with me at Netscape. Specifically, thanks to Sean Su, formerly of
Netscape and now at AOL, who took the time to read an early draft of Item
15 and give me his feedback. Jim Dunn, my first manager at Netscape,
helped me get my facts straight regarding the development of the Netscape
4.x browser. Doug Turner, also from Netscape, and now at Mozilla,
provided plenty of constructive feedback, leading to the addition of several
Acknowledgments
=
xxiii
pages to the manuscript. Roy Yokohama, who was a senior international-
ization engineer at Netscape, took the time to provide many useful
comments related to my coverage of internationalization and localization in
wxWidgets. Others who provided helpful feedback include Netscapers
Stephen Morse and Namachivayam Thirumazshusai (Shiva). Thanks also go
to Kevin McCluskey, who wrote the book’s Foreword, and who taught me
so much back when we worked together at Netscape’s San Diego office.
Thanks to all of my friends, who helped me to keep a proper perspective
on life during the long process of getting this book done; and to Mei, for
giving me the time, space, and encouragement needed for me to see this
project to its completion during its final stages.
xxiv Acknowledgments

×