Posted by richburridge
on April 28, 2004 at 11:17 AM PDT
People should think of open source code portability
on two levels; system/library calls and graphical calls.
Recently I've been trying to get various open source applications
running on Solaris on x86 machines. These were mostly GNOME
applications, but some of them were dependant upon underlying
libraries that come from the Linux world. I've been having some
trouble with some of these software distributions because the
author(s) have only ever been concerned with GNOME and Linux.
I'm old enough to remember a time (15-20 years ago) when SunOS
(the predecessor to Solaris) was the preferred Unix development
environment and porting to other flavours of Unix was secondary.
Linux is the main "Unix" development environment now. Fair enough,
but developers should still think about what it would take to get
their software working on other operating systems like Mac OSX,
Windows and Solaris. It's not hard to abstract the differences out.
It would give you the benefit of having a much larger potential
user base too.
Differences come in two types here. Operating system calls and
library API calls I group together. Then the second type is graphics
calls. Let's talk about the system calls and library API's first.
Some people prefer huge #ifdef/#endif sections in their code to
capture these O/S specific differences. My favorite approach is
for your configure (or build) script to determine the type of
platform you are running on, then compile a single different file
depending upon that O/S type. That file would contain the O/S specific
calls in a single place, each call in a separate routine with a common
abstract name. The other files in the software distribution call
these abstract routines and the build picks up and compiles
the specific O/S file containing these routines and just does the
right thing. It's clean, easy to understand and if your application
has to be ported to several additional platforms at the same time,
this can be done by multiple developers efficiently and in parallel
without stepping on each others toes.
Handling graphics calls I believe should be done in a similar manner.
Too many times I've seen an application written with just one
graphical toolkit in mind. And with these graphics calls being done
in all the source code files. Experience has shown me that a graphics
toolkit has a life expectantcy of 5-8 years (some less than that).
Then something better comes along. Or you need to port to another
platform which doesn't support the original toolkit. Porting to another
toolkit is then a nightmare.
I've been writing open source code for about 19 years now. Open
source graphical code for about 16 years. The approach I've taken is
to abstract all the graphics calls out into a single file that's
specific to a particular toolkit. This contains routines with names
like "draw_frame", "make_button". The routines in that single file
then contain implementations of the required functionality using that
toolkit API. Porting to another graphical toolkit is a simple case of
creating another file with those abstract names in, and providing
calls to the new toolkit within. Plus a little glue in your configure
(or build) script to make sure that the correct one is compiled
depending upon the platform you are running on.
Using this approach, I'm still able to use today a calcalator program
that was originally written in 1987. It's seen numerous toolkits
(SunView, X11, NeWS, XView, Motif, MGR, Gtk+ and even a curses version)
and it's worked on numerous UNIX systems (plus a version that runs
in an embedded system).