As Linux has gained in popularity, the number of commercial (and free) applications have risen dramatically. A growing number of these applications were not born on Linux but rather on some other, lesser known operating systems. Obviously, this is a wonderful trend and one that I am personally quite happy to see. In fact, this article itself was drafted using Star Office, an office suite for Windows and several other Operating Systems. Call it a trial by fire. However, many of these newcomers to the Linux realm of computing carry with them many of the quirks and traits of previous OSes. This article attempts to describe some of the things that application porters can do to make their applications more Linux-like and play nicer with the conventions already established by the community. It is my hope that someone out there someplace will see this and say "Wow, I was about to do that. How silly I feel now. I'll fix that right away!" and maybe help make the Linux environment that much more enjoyable.
Of course, many of these so-called flaws are present in current Linux applications that are otherwise well-behaved. It's my idea of an optimal world which I have extracted from Linux history. Maybe the writing is on the wall and I'm showing my age and that these ideas, in whole or in part, are obsolete. Whatever you think, please let me know. I'd love to hear from Linux developers who are facing these issues and I hope that writing this will promote thought on the subject.
Generally, a Linux application's configuration can be split into two distinct parts: the master configuration and the per-user configuration. This allows Linux applications to be customized to each individual user's tastes without settings carrying over. The master configuration file or directory is generally stored with the other files for the application (for example, /usr/share/foo) or in the /etc directory if the application is to be considered "low-level". (I generally prefer to not clutter the /etc directory with high-level configuration bits but that's not always the case.) Now, while this file should be considered for default options, end users should have their settings saved into their own home directories. By tradition, this is often done with a dotfile or directory. For example, a user of application foo could likely expect to find their per-user configuration bits in .foo/ (a directory with multiple config files) or .foorc (or some other similarly named file.) This separation is easily enforceable as most user accounts should not have write access to the directory where the application is stored.
Some Linux applications, when run as the root user, will modify the master config files rather than the per-users files. This would make any changes done as the root user global. Application writers can consider this approach for simplicity of administration, but many administrators are comfortable with merging in changes by hand as necessary. (Provided they are human-readable, see below.)
When writing install programs, it's important to remember that not all applications will be installed globally. Often, a particular user will want to install the program for him or herself only and the install should be smart enough to know the difference. When running as root, an installer should expect to put the application in a public place (for example, /usr/share.) When running as a user, the installer should suggest putting the application in a directory off the user's home. If the installer suggests root's home for a global install, no one is likely to have access to the files and the entire purpose of running as root is ruined. This type of separation work does take extra time to code but the benefit to end users in the Linux world is enormous.
One such annoyance is with command-line options. Now, I'll be the first to admit that not all Linux applications are consistent when it comes to options and how they are formatted. However, there are some general rules to follow. Under Linux, the forward-slash is a path delimiter and not an option mark. Thus, while "foo /bar" is acceptable in the Windows world, it can be quite confusing in the Linux world. For the end user, it is quite difficult to determine whether /bar is an option or a full path. Some shells may get confused. And what if you do need to pass an actual path (for example, a file to open) to such a program? How is it to figure out (besides cruel hackery) what is a path and what is an option?
The answer, of course, is to use GNU-style option syntax. For long options, use double dashes. With the example above, the new syntax would be "foo --bar" For shorter options, Linux applications generally use a single dash. "-b", for example, might be an abbreviated form of --bar.
If you are porting a program from the MacOS or Be, it might be useful to think about adding command-line options to your programs. Linux users demand some level of batch control in their applications. In its most simple forms, these can be nothing more than options to open a file by default. However the perfect Linux application will have plenty of options that can allow the end user to have some flexibility in the way that config files are loaded, what input files to open by default, and just about anything else that would allow him or her to use your program in a customized environment.
By the same token, many applications written for alternative OSes do not take advantage of the standard input and output devices. Applications that are written for the Linux environment should not forget that these devices exist for the convenience of the end user. In a customized environment, standard input may be the best way of getting data into your application (for example, from a pipe.) If your application supports batch processing, having an option to write to standard output is a wonderful idea. Just because your application is a windowing application shouldn't mean that it's disconnected completely from the power of the command-line.
In my opinion, applications written for many other OSes are constricted by artificial barriers and shortsightedness. These applications' uses are limited to the imaginations of the programmers. A good Linux application, on the other hand, should be flexible, well-designed, and limited only by its user's imagination.
If you are porting an existing codebase to Linux, you probably already have plenty of documentation available in either your own format or the format of the previous OS. In some cases, such as OSes with HTML help, you'll have no problems translating help there to help on Linux. In other cases, I recommend that you try and steer away from any proprietary formats on a Linux system as most Linux applications natively do. Don't limit your users to use your specific help browser (even if there are some features, such as a macro-based tutorial, that can only be accessed through it), but rather allow them to see the information in some other way (without all the dazzle.) There are indexing tools and other oddities in the Linux world that many users use and keeping documentation readable keeps these options up to the end user, your customer. For documentation, I recommend HTML or plain text; Linux readers are available for postscript, portable document format (.pdf), and other formats but many users will find these limiting in some way or another.
If your program has command line options, you should consider making up a one page summary of the options and storing it in manual format. This gives the user a quick reference in the traditional format. It should probably contain a pointer to "real" documentation, the software company's website, and anything else appropriate. Simple things like these make the difference between a good program and a great program.
Frankly, I just like text files because they can be edited easily in whatever program I prefer. I'm a vi man myself, although pico is quite nice. Emacs scares me, mostly because I'm not allowed to use it at work. (Please, don't anyone flame my employer. I like my job.) But it's not just a matter of text editing, it's about having options. What if someone wants to write a configuration GUI that makes your program easier or more integrated into the OS? A difficult file format stands as a barrier between you and something that can improve on your product.
By the same token, hiding extensions from users can be annoying. Sure, Linux "desktop" developers may choose to make this mistake, too. But that doesn't mean that everyone should. Similarly, putting your own VFS (Like with the "Desktop" on top.) on top of the existing system for file dialogs may seem easier to understand, but the lack of consistency across applications will cause confusion. Hiding the filesystem (or just about anything else) from the user is, in my opinion, a bad move.
When porting an application to Linux, one has a lot of widget options to choose from. Motif may be a bad move as it's commercial, but Qt and Gtk+ are both good options and both supported on most distributions. (Flamewars aside, they are both wonderful widget sets.) Writing your own widget set from scratch may seem like a good idea, but it's a wasted effort with so many other options abounding. (People will be sending me email saying that having a desktop full of some Qt and some Gtk+ is bad and that Linux users should just make up their minds. I think that I'd rather have the option and at least Linux widget sets are being used. Besides, both sets are themable to look like the other, more or less.)
In a somewhat more extreme situation, some ported applications even take pieces of their former OS with them. For example, StarOffice adds a Start button. This blatant MS-ism not only is unnecessary (a menu or a toolbar would be just as functional), it gets in the way of my Gnome panel. To me as an end user, this actually reduces the functionality of the application to such an extent that either the Gnome panel or the StarOffice "Start" bar has to be hidden and worthless to me. I appreciate that they want to make Linux familiar to Windows users, but it would be nice to make Linux familiar to Linux users.
Thanks. Happy New Year!
Joe Pranevich (recently relocated to Boston. Yay.)