oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Creating Easy-to-Deploy Unix Applications for OS X

by Mark Roseman

Rather than Mac OS X bringing an explosion of exciting Unix software to Mac users, we're instead seeing countless articles on Mac web sites describing the arcana of command lines and configuration files, .tar files and Perl scripts. What happened?

As an example, Giles Turnbull wrote a long article for describing the steps needed to get PHPWiki, a very nice Wiki server application written in the Unix scripting language PHP, up and running on Mac OS X. Originally designed for "standard" Unix platforms such as Linux rather than Mac OS X, many pages were needed to describe in excruciating detail the steps needed to get PHPWiki running. These included:

Related Reading

Mac OS X Panther for Unix Geeks
Apple Developer Connection Recommended Title
By Brian Jepson, Ernest E. Rothman

  • Download and unpack the latest source in your Sites directory.
  • In Terminal, use vi under sudo to edit Apache's configuration file to allow it to use PHP, and then restart Apache.
  • Download and install MySQL, and using several more command lines, set up a database password and database tables for PHPWiki to use.
  • Modify one of PHPWiki's code files to tell it about the database.

In contrast, my company's Wiki application, ProjectForum, has simpler instructions: Double-click.

With OS X's Unix foundations came the promise of access to thousands of Unix applications for Mac users. But if those applications are hard to install, configure, and use, everyone loses. Potential users may waste a lot of time, get frustrated, and eventually even give up on a fundamentally useful piece of software, while developers lose the opportunity to see their hard work benefit many more people.

So what to do? This article describes some of the most common obstacles to deploying Unix software on Mac OS X. The good news is that software developers can remove these obstacles for users, often with only small changes to their development practices.

I'll illustrate some of these with ProjectForum, which was developed primarily with Tcl, a typical Unix scripting language. ProjectForum is a powerful cross-platform Wiki server (Figure 1) that needed to be extremely easy to install and use by our target audience.

Figure 1. A ProjectForum site.

Deployment Obstacle #1: Dependencies

Unix applications, whether written in C, C++, Java, Perl, Python, Tcl, PHP or another language, tend to depend on many other packages and code libraries. By leveraging other people's code, developers save time by focusing on the code unique to their own application. Most Wikis, for example, rely on external databases (e.g. MySQL), web servers (e.g. Apache), version control systems (e.g. CVS), scripting language interpreters, web-form processing libraries, and more.

While you as a developer save time, whenever someone wants to try your application, they are often forced to locate, download, install, and configure each of these packages, if they aren't already available on the system. These may be non-trivial steps, particularly on platforms like Mac OS X where users aren't generally knowledgeable about installing Unix software. Any hesitation, problem, or error will result in the user abandoning your application.

Removing the Dependencies

If we can reduce the dependencies on large external packages, we remove some big obstacles in front of users trying to install and run our applications. Two approaches can be helpful here: using embeddable tools, and developing new, minimal subset tools.

Replacing an external tool that must be set up separately with one that can be bundled right into our application means that the user need not have to install it separately. Databases are a great example; while some applications certainly do need all of the power of external databases like MySQL or Oracle, for most applications with modest storage needs, they are complete overkill.

There are some great embeddable database libraries out there, such as MetaKit (which we used in ProjectForum) and SQLite. With an embeddable database, your application links directly with a library that manipulates the database, rather than communicating with an external database server process. The database is part of your application, not a separate process.

Similarly, do you really need all the flexibility and power of the Apache web server? For your particular application, could a simpler, embeddable web server (e.g. TclHttpd, Twisted, etc.) suffice? Again, by making the web server part of your application, your users don't have to make sure Apache is set up and configured with the right settings, and that your application files are placed in exactly the location where Apache expects to see them.

When embeddable tools aren't already available, you may benefit from building your own minimal subset library, to be included as part of your program. For the five percent of CVS functionality we wanted to have available in ProjectForum, it made more sense developing a small code module in Tcl and MetaKit, rather than asking all of our users to install CVS.

While some applications may truly need all of the flexibility and power of external tools, the decision to include each one should be carefully considered, taking into account developer effort and technical feasibility, as well as the size and skill level of the target audience. Do the benefits obtained by the developer outweigh the costs to each user?

Relying on embeddable tools (whether existing ones or those you develop) means everything can be bundled with your application. Users don't have to install and configure a variety of other packages separately just to use your application.

Deployment Obstacle #2: Packaging

Most Unix applications are made available as "tar balls" of source code, which need to be unpacked, compiled by users (e.g. via command-line tools), and then installed. Applications written in scripting languages can skip the compilation step, but often must be carefully installed, with different pieces going into particular directories (e.g. a web server's documents directory), often scattered across the disk.

For Mac users, this is foreign territory. Compilers and other developer tools are typically not installed in the first place; nor are users expected to even have knowledge of the Unix shell. Native Mac applications can be installed by simply dragging them anywhere on the user's machine, and run by double-clicking them. Anything else invites hesitation, frustration, and errors, with your application landing in the Trash Can, not the Applications folder.

Package for Your Users

Even if you're also making the source code for your application available, providing pre-compiled binaries directly to your users is a smart thing to do.

This is absolutely essential for applications written in compiled languages, but usually makes sense for applications written in scripting languages, too. Most scripting languages have tools (e.g. FreeWrap and Python's Freeze) you can use to "wrap up" all of your scripts and other data, along with the scripting language interpreter itself (removing yet another dependency!), into a single binary.

A particularly nice wrapper for Tcl is Starkit, which allows you to wrap up an entire directory tree into a single file "virtual filesystem," so that the application is structured the same on the user's machine as it is in the development environment. End users see just a single file application, while other developers can easily access the underlying code. When source code protection is needed, additional tools like Tcl Dev Kit's Compiler are also available.

Rather than receiving tar balls, Mac users expect to download their applications as disk images, which are mounted on their desktops as CDs would be. The application on the disk image can then be dragged to its own hard disk. Installers can be used when multiple files must be installed in different places on the disk, or for other complex needs, but if possible, restructuring your application to reduce this need is preferred. But anything is better than having users manually copy multiple files around! Both disk images and installers can be easily created using free utilities.

For ProjectForum, we take the same cross-platform Starkit used for other Unix and Windows platforms, bind it with the OS-X-specific runtime to create a standard Mac application, and then stuff the whole thing into an OS X disk image, all from a 50-line shell script. The result is a single, self-contained application, shipped as a disk image, well under 2Mb in size.

The end goal is that your users shouldn't need to know that your application was written with standard Unix tools; it should be indistinguishable from a native OS X application.

Deployment Obstacle #3: Configuration

Once everything is compiled and installed, there is still the matter of getting an application configured. Here too, Unix applications often tend to make things more difficult than they need to be.

Many Unix tools rely on hand editing of configuration files, i.e. the user must open up a text editor and modify some parameters in a file located at a particular place on disk. It's not unusual for this process to change some variables at the top of a program's code. Needless to say, one wrong keystroke, and the program might stop working altogether.

Reduce and Simplify Configuration

Most applications can benefit from reducing the amount of configuration that is required before running. With sensible defaults and, possibly, judicious examination of the environment in which the program is running, there shouldn't be much need for any required configuration.

After the program has started, it's better to handle any subsequent optional configuration changes within the program itself, preferably via a well-presented, standard Aqua user interface. For network applications, configuration via a web browser interface is another option. Regardless, your configuration interface should be designed to meet your users' needs and expectations, providing sensible choices for changing options in a safe and robust manner.

Deployment Obstacle #4: Is it Running?

A final obstacle, particularly for many network server applications, is providing the user with decent feedback that the program is running. Server applications, and many other types of software on Unix, are usually designed to run without any kind of user interface. They are started (from a command line) and simply run, with no feedback to the user.

If you've followed the recommendations on packaging, your application already looks like a regular Mac application that is double-clicked in the Finder, rather than run from a command line. But what happens when you double-click an application with no user interface? It starts, but nothing shows up. How can the average user differentiate this from an application that just crashed on startup? What do they do next? How can they stop the thing?

Provide Feedback, Even for Servers

In ProjectForum, which is a typical server application, we display a small user interface when the application is running (Figure 2).

Figure 2. ProjectForum Launcher User Interface.

Providing this very simple user interface provides a number of benefits to the user:

  • It provides immediate feedback that the program is running, even for users who may not be familiar with running servers.
  • In case of serious startup problems (e.g. network port conflicts), we can offer the option of selecting a different port.
  • There is an obvious mechanism for stopping the server.
  • The "Open in Browser" button provides an easy way for the user to access the application, rather than needing to know a particular URL to type into his or her web browser.

"Great," you're thinking, "now I have to go learn details about Mac programming just to build a special user interface for my server application." Relax, it's easier than you think. Using Apple's excellent (and free!) developer tools like Project Builder and Interface Builder, we put together the simple Cocoa front end for ProjectForum in less than a day -- including time spent learning Cocoa and the developer tools!

This front end became the main application that is launched when the user double-clicks ProjectForum. The Cocoa application then executes the underlying wrapped Tcl application (a single Unix-style executable), communicating with it using standard Unix pipes. Simple textual commands are sent to start the server on a given port, stop it, and so on.

More experienced users can run the underlying Unix executable directly, without the user interface. This can be useful when the program needs to be run without user intervention; e.g., when the computer first boots (which is done using special shell scripts called "Startup Items" on OS X).

Deployment Counts

While historically there was some element of "if it was difficult to write, it should be difficult to install and use" bravado in the Unix culture, for modern Unix users (and especially Mac OS X users wanting to take advantage of some excellent Unix software), this attitude is best left in the past.

For Unix developers, this article has suggested some important deployment obstacles that can prevent Mac users from fully taking advantage of your software, and provided techniques to overcome those obstacles.

In our case, using those techniques has allowed us to continue to use high-productivity development tools such as Tcl to build ProjectForum, while still producing an application that is extremely easy to install and use for Mac OS X users.

Users would be hard-pressed to distinguish it from an application built exclusively with native Mac tools, and isn't that really the point? Ultimately, the design decisions we took resulted in an application that was easier to deploy, and that benefited our Unix and Windows versions, as well.

Decisions about deployment very often result in tradeoffs for developers. If you use a particular technology, it may provide a lot of advantages, but may make deployment more difficult. I'm not suggesting you never use such technologies, but make sure that it's a conscious decision -- one that factors in the true deployment costs to users. Because these decisions have a huge effect on your development, it's critical they be considered very early in the development process.

Context matters too, of course: a one-off custom application that you will be installing yourself is a lot different than a mainstream application that thousands of users may download and try to install themselves. If your application could benefit a wide audience, you owe it to yourself and your potential users to spend a little bit of extra time thinking about deployment.

There are some great Unix applications out there, and many more still to be written. Let's hope that some of the techniques discussed here will help make them easier to install and use so that everyone, including Mac users, can reap the benefits.

Mark Roseman is a senior software developer currently living in Ontario, Canada. He founded and runs CourseForum Technologies, while contributing to several open source projects.

Return to the Mac DevCenter