Programming for Portability (2024)

Software portability is usually thought of in quasi-spatialterms: can this code be moved sideways to existing hardware andsoftware platforms other than the one it was built for? But Unixexperience over decades tells us that durability down through time isjust as important, if not more so. If we could predict the future ofsoftware in detail it would probably be the present —nevertheless, in programming for portability we should try to thinkabout making choices that will base the software on the features ofits environment that are likeliest to persist, and avoid technologiesthat seem likely to face end-of-life in the foreseeable future.

Under Unix, two decades of attention to the issues ofspecifying portable APIs has largely solved that problem. Facilitiesdescribed in the Single Unix Specification are likely to be presenton all modern Unix platforms today and rather unlikely to go unsupported in the future.

But not all platform dependencies have to do with the systemor library APIs. Your implementation language can matter; file-systemlayout and configuration differences between the source and targetsystem can be a problem as well. But Unix practice has evolved ways to cope.

Portability and Choice of Language

The first issue in programming for portability is your choice ofimplementation language. All the major languages we surveyed in Chapter14 are highly portablein the sense that compatible implementations are available across allmodern Unixes; for most, implementations under Windows and MacOS areavailable as well. Portability problems tend to arise not in the corelanguages but in support libraries and degree of integration with thelocal environment (especially IPC and concurrent-process management,including the infrastructure for GUIs).

C Portability

The core C language is extremely portable. The standard Uniximplementation is the GNU C compiler, which is ubiquitous not only inopen-source Unixes but modern proprietary Unixes as well. GNU C hasbeen ported to Windows and classic MacOS, but is not widely used ineither environment because it lacks portable bindings to the nativeGUI.

The standard I/O library, mathematics routines, andinternationalization support are portable across all Cimplementations. File I/O, signals, and process control are portableacross Unixes provided one takes care to use only the modern APIsdescribed in the Single Unix Specification; older C code often hasthickets of preprocessor conditionals for portability, but thosehandle legacy pre-POSIX interfaces from older proprietary Unixes that are obsolete or close to it in 2003.

C portability starts to be a more serious problem near IPC,threads, and GUI interfaces. We discussed IPC and threads portabilityissues in Chapter7. The real practical problem is GUItoolkits. A number of open-source GUI toolkits are universallyportable across modern Unixes and to Windows and classic MacOS as well— Tk, wxWindows, GTK, and Qt are four well-known ones with sourcecode and documentation readily discoverable by Web search. But noneof them is shipped with all platforms, and (for reasons more legalthan technical) none of these offers the native-GUI look and feel onall platforms. We gave some guidelines for coping in Chapter15.

Volumes have been written on the subject of how to write portable C code. This book is not going to be one of them. Instead,we recommend a careful reading of Recommended C Style and Coding Standards [Cannon]and the chapter on portability inThe Practice of Programming [Kernighan-Pike99].

C++ has all the same operating-system-level portability issues as C,and some of its own.An additional one is that the open-source GNU compiler for C++ haslagged substantially behind the proprietary implementations for mostof its existence; thus, there is not yet as of mid-2003 auniversally deployed equivalent of GNU C on which to base a de-factostandard. Furthermore, no C++ compiler yet implements the full C++99ISO standard for the language, though GNU C++ comes closest.

Shell Portability

Shell-script portability is, unfortunately, poor. The problemis not shell itself;bash(1)(the open-source Bourne Again shell) has become sufficientlyubiquitous that pure shellscripts can run almost anywhere. Theproblem is that most shellscripts make heavy use of other commands andfilters that are much less portable, and by no means guaranteed to bein the toolkit in any given target machine.

This problem can be overcome by dint of heroic effort, as in theautoconf(1)tools. But it is sufficiently severe that most of the heavier sort ofprogramming that used to be done in shell has moved tosecond-generation scripting languages like Perl, Python, and Tcl.

Perl Portability

Perl has good portability. Stock Perl even offers a portable setof bindings to the Tk toolkit that supports portable GUIs acrossUnix, MacOS and Windows. One issue dogs it, however. Perl scripts oftenrequire add-on libraries from CPAN (the Comprehensive Perl ArchiveNetwork) which are not guaranteed to be present with every Perlimplementation.

Python Portability

Python has excellent portability. Like Perl, stock Python evenoffers a portable set of bindings to the Tk toolkit that supportsportable GUIs across Unix, MacOS, and Windows.

Stock Python has a much richer standard library than doesPerl and noequivalent of CPAN for programmers to rely on; instead, importantextension modules are routinely incorporated into the stock Pythondistribution during minor releases. This trades a spatial problem fora temporal one, making Python much less subject to the missing-moduleeffect at the cost of making Python minor version numbers somewhatmore important than Perl release levels are. In practice, thetradeoff seems to favor Python.

Tcl portability is good, overall, but varies sharply by projectcomplexity. The Tk toolkit for cross-platform GUI programming isnative to Tcl. As with Python, evolution of the core language hasbeen relatively smooth, with few version-skew problems.Unfortunately, Tcl relies even more heavily than Perl on extensionfacilities that are not guaranteed to ship with every implementation— and there is no equivalent of CPAN to centrally distributethem.

For smaller projects not reliant on extensions, therefore, Tclportability is excellent. But larger projects tend to depend heavilyon both extensions and (as with shell programming) calling externalcommands that may or may not be present on the target machine; theirportability tends to be poor.

Tcl may have suffered, ironically, fromthe ease of adding extensions to it. By the time a particular extensionstarted to look interesting as part of the standard distribution, theretypically were several different versions of it in existence. At the1995 Tcl/Tk Workshop, John Ousterhout explained why there was no OOsupport in the standard Tcl distribution:

Think of five mullahs sitting around in a circle, all saying“Kill him, he's a heathen”. If I put a specific OOscheme into the core, then one of them will say “Bless you, myson, you may kiss my ring”, and the other four will say“Kill him, he's a heathen”.

The lot of a language designer is not necessarily a happy one.

Java Portability

Java portability is excellent — it was, after all,designed with “write once, run everywhere” as a primarygoal. Portability fails, however, to be perfect. The difficulties aremostly version-skew problems between JDK 1.1 and the older AWT GUItoolkit (on the one hand) and JDK 1.2 with the newer Swing GUI toolkit.There are several important reasons for these:

  • Sun's AWT design was so deficient that it had to be replaced with Swing.

  • Microsoft'srefusal to support Java development on Windows and attempt to replaceit with C#.

  • Microsoft's decision to hold Internet Explorer's applet support at the JDK 1.1 level.

  • Sunlicensing terms that make open-source implementations of JDK 1.2impossible, retarding its deployment (especially in the Linuxworld).

For programs that involve GUIs, Java developers seekingportability will, for the foreseeable future, face a choice: Stay inJDK 1.1/AWT with a poorly designed toolkit for maximum portability(including to Microsoft Windows), or get the better toolkit andcapabilities of JDK 1.2 at the cost of sacrificing someportability.

Finally, as we noted previously, the Java thread support hasportability problems. The Java API, unlike less ambitiousoperating-system bindings for other languages, bravely tried to bridgethe gaps between the diverging process models offered by differentoperating systems. It does not quite manage the trick.

Emacs Lisp Portability

Emacs Lisp portability is excellent. Emacs installations tend tobe upgraded frequently, so seriously out-of-date environments arerare. The same extension Lisp is supported everywhere and effectivelyall extensions are shipped with Emacs itself.

Then, too, the primitive set of Emacs is quite stable. Itachieved completeness for the things an editor has to do (manipulatingbuffers, bashing text) years ago. Only the introduction of X hasdisturbed this picture at all, and very few Emacs modes need to beaware of X. Portability problems are usually manifestations of quirksin the C-level bindings of operating-system facilities; control ofsubordinate processes in modes like mail agents is about the onlyissue where such problems manifest with any frequency.

Avoiding System Dependencies

Once your language and support libraries are chosen, the nextportability issue is usually the location of key system files anddirectories: mail spools, logfile directories and the like.The archetype of this sort of problem is whether the mail spooldirectory is /var/spool/mail or/var/mail.

Often, you can avoid this sort of dependency by stepping backand reframing the problem. Why are you opening a file in the mailspool directory, anyway? If you're writing to it, wouldn't it bebetter to simply invoke the local mail transport agent to do it foryou so the file-locking gets done right? If you're reading from it, might it be better to query it through a POP3 or IMAP server?

The same sort of question applies elsewhere. If you findyourself opening logfiles manually, shouldn't you be usingsyslog(3)instead? Function-call interfaces through the C library are betterstandardized than system file locations. Use that fact!

If you must have system file locations in your code, your bestalternative depends on whether you will be distributing in source codeor binary form. If you are distributing in source, theautoconf tools we discuss in the nextsection will help you. If you're distributing in binary, then it'sgood practice to have your program poke around at runtime and see ifit can automatically adapt itself to local conditions — say, byactually checking for the existence of /var/mail and /var/spool/mail.

Tools for Portability

You can often use the open-source GNUautoconf(1)we surveyed in Chapter15 tohandle portability issues, do system-configuration probes, and tailoryour makefiles. People building from sources today expect to be ableto type configure; make; make install and get aclean build. There is a good tutorial on thesetools. Even if you're distributing in binary, theautoconf(1)tools can help automate away the problem of conditionalizing your codefor different platforms.

Other tools that address this problem; two of the better knownare theImake(1)tool associated with the X windowing system and the Configure tool built by Larry Wall (laterthe inventor of Perl) and adapted for many differentprojects. All are at least as complicated as the autoconf suite, andno longer as often used. They don't cover as wide a range of targetsystems.

Programming for Portability (2024)
Top Articles
Latest Posts
Article information

Author: Ms. Lucile Johns

Last Updated:

Views: 5586

Rating: 4 / 5 (61 voted)

Reviews: 84% of readers found this page helpful

Author information

Name: Ms. Lucile Johns

Birthday: 1999-11-16

Address: Suite 237 56046 Walsh Coves, West Enid, VT 46557

Phone: +59115435987187

Job: Education Supervisor

Hobby: Genealogy, Stone skipping, Skydiving, Nordic skating, Couponing, Coloring, Gardening

Introduction: My name is Ms. Lucile Johns, I am a successful, friendly, friendly, homely, adventurous, handsome, delightful person who loves writing and wants to share my knowledge and understanding with you.