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.
Dealing with Multiple Users
One of the biggest changes that application developers have to cope with when moving to a Linux environment is the user. Windows doesn’t have users, really. Under many other OSes, applications do not generally support separating configuration files, documents, and other files so that different users get his or her own personalized environment. Even on OSes that support multiple users (such as Windows), very few programs bother to make use of these features and instead opt to put configurations in global places. Linux, on the other hand, does have multiple users and applications should always be written with this in mind.
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.
Working on the Command Line
The devil, as they say, is in the details and it is often the subtle flaws in an application that can make it more painful for the Linux end user. Most of these flaws are readily avoidable and not difficult to fix.
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.
Documentation
Documentation under Linux can be a tricky subject. I don’t want to get into any flame wars over manual pages and info pages or about any budding standard. In my mind, convenience is the number one reason for documentation and help that cannot be read can’t be construed as very helpful.
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.
Configuration Files
To a Linux user, being able to configure a system in whatever manner you prefer is important. To that end, Linux applications generally have config files that can be edited using a standard text editor. While there is no set standard for Linux configuration files (for example, Windows’s old .ini format), any format that is generally understandable is appropriate. What is definitely not appropriate is registry-like binary files that require specific applications to edit them. Back in high school, I worked in a computer store as a technician for a couple years and there is no problem on the face of the earth more annoying than trying to get Windows to start up when the registry file is corrupted. Using the Linux ideal of text files, you at least stand a chance at being able to edit the file into working again.
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.
Linux isn’t Windows
This simple rule is hard to express too much. Linux isn’t Windows. Linux isn’t the MacOS. Whether you are writing documentation or dialog boxes, don’t get your terminology confused. Many Linux users can become annoyed or confused when confronted by MS-isms. For example, Linux doesn’t have folders. Instead, Linux has directories. We’re not afraid to say the word directory. Similarly, we don’t generally call things shortcuts. (They’re symlinks.) There are more examples, of course, but the point is that using “cutesy” words for concepts when we have perfectly good words already can be confusing to users, especially those who have not come from whatever world you did.
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.
Don’t Reinvent the Wheel
A growing trend in newer ported applications seems to be that they hang onto their roots very strongly, even artificially. Some applications deliberately make their widgets look more like the widgets on the old system. Some applications even go so far as to draw their own windows so that they can use little minimize buttons. Linux users don’t need these things. In fact, many Linux users will find this artificiality disconcerting. They destroy the standardization of the user’s look-and-feel. In general, it’s a bad thing.
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.
Everyone has a Port
Linux users are turning more and more towards platforms other than x86. I personally have Linux running on an Alpha and an old m68k system. While I can admit that I am not necessarily a typical user, I cannot understand why companies would choose to limit their own customer base when they do not need to. The sad fact is, however, that many commercial (and source-less) Linux applications are available only for Linux/i386 and no other port. Now, I can understand that it isn’t reasonable to support each and every piece of hardware that Linux does; that would be impossible! But even handling the “big” ones (like Alpha, PPC, and Sparc) would increase the number of paying customers at almost no cost. As I keep saying over and over again: Linux users like their flexibility.
Some Notes about Wine and WineLib
Let me start off by saying that Wine, the Windows emulator (or non-emulator), is a great product. I use it at work to run Lotus Notes. I’ve written a good amount of code for the project. I’m in the authors’ list (quite proudly!). But, when it comes to porting applications to Linux, it’s not a good long-term option. For a first release, Wine is great. It gets the product into people’s hands. But what it doesn’t do is provide a good Linux experience. It’s quite frankly a lot of overhead and doesn’t mesh well (yet) with Linux applications on a side-to-side basis. A true Linux application should be written for Linux and I guarantee that it will be a thousand times better that way. Of course, that’s just my opinion. Anything that gives more options, even options in emulation, is a good one and Wine is a wonderful option. (Especially to get around silly things like corporate email policies that don’t consider other OSes.) Conclusion
These are just my thoughts on porting applications to Linux and tangentially on Linux application programming in general. I’d love to discuss this list and see what your own personal gripes are, what you feel is right and wrong, and where you think Linux is going. Maybe a Gnome or KDE developer would be willing to chime in his or her two cents. If there’s enough interest, I’ll write a follow-up story about how wrong all my opinions are. In the end, I hope that through writing this I have given someone pause for thought.
Thanks. Happy New Year!
Joe Pranevich (recently relocated to Boston. Yay.)