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.)