version() abuse! Note of library writers.

Travis Boucher boucher.travis at gmail.com
Tue Nov 17 12:11:14 PST 2009


The use of version(...) in D has the potential for some very elegant 
portable code design.  However, from most of the libraries I have seen, 
it is abused and misused turning it into a portability nightmare.

http://dsource.org/projects/dmd/browser/trunk/src/mars.c#L313 defines 
the following versions: Windows, Posix, linux, OSX, darwin, FreeBSD and 
Solaris.

http://dgcc.svn.sourceforge.net/viewvc/dgcc/trunk/d/target-ver-syms.sh?view=markup 
defines aix, unix, cygwin, darwin, freebsd, Win32, skyos, solaris, 
freebsd (and others).

The problem I run into is the assumption that linux == unix/posix.  This 
assumption is not correct.

The use of version(linux) should be limited to code that:

1. Declares externals from sys/*.h
2. Accesses /proc or /sys (or other Linux specific pseudo filesystems)
3. Things that interface directly with the dynamic linker (eg. linking 
against libdl)
4. Other things that are linux specific....

Anything that accesses standard libc functions, standard unix semantics 
(eg. signals, shm, etc) should use version(Posix) or version(unix).

Build systems and scripts that are designed to run on unix machines 
should not assume the locations of libraries and binaries, and refer to 
posix standards for their locations.  For example, bash in /bin/bash or 
the assumption of the existence of bash at all.  If you need a shell 
script, try writing it with plain bourne syntax without all of the bash 
extensions to the shell, and use /bin/sh.  Also avoid using the GNU 
extensions to standard tools (sed and awk for example).  If you really 
want to do something fancy, do it in D and use the appropriate {g,l}dmd 
-run command.

A few things to keep in mind about linux systems vs. pretty much all 
other unix systems:

Linux is a kernel.  The userspace stuff you use (your shell, your libc, 
etc) is (typically) GNU, and not Linux.  On other unix systems, the 
kernel is tightly linked to the libc and other standard libraries, and 
the other base applications (shell, login, sed, awk, etc) are often part 
of the base system and not GNU (this is not always true, as some systems 
use GNU tools as part of the base system as well).

If you are writing a wrapper around something, and it is a library in 
Linux, it most likely is also a library in other unix machines.  This 
includes opengl, image libraries, X11 libraries, sound & media 
libraries, etc.  If you require an external library, please state as 
much in the documentation and don't hide it in a version(linux) 
statement because you just abused the reason for version(...) to exist 
in the first place.

Other tips:
  - Don't use the /proc filesystem unless you really must.  If you do, 
abstract the interface and implement a Linux specific interface.  This 
will ease porting (I'd be happy to come in and do FreeBSD stuff where 
possible).
  - If you are unsure, check http://www.freebsd.org/cgi/man.cgi This 
interface can look up the manual pages for multiple OSes, and the 
FreeBSD versions of the manuals are very consistent.  Some of the other 
ones will also give hints on bugs and subtle differences for different 
implementations.
  - If you want to make something work under FreeBSD or other OSes, post 
on the NG (or for FreeBSD, bug me directly).
  - Linux programs need to be linked against libdl for access to 
dlopen() and family, most unix OSes have access to dlopen() from libc (I 
think this is partially due to the tight libc/kernel coupling in most 
unix OSes).
  - Darwin/OSX & FreeBSD all share alot of similar kernel interfaces, 
specifically most of the process model, network stack and virtual 
filesystem layers.  OSX even has kqueue! (although slightly different 
then FreeBSD).
  - FreeBSD & Solaris share some common ancestry.  Although the 
similarities are not very important to application developers, internal 
kernel interfaces and designs are similar.
  - The GNU tools typically conform to standards, but add extra 
extensions everywhere.  If you write your scripts for a standard bourne 
shell rather then bash, bash will still be able to run it most of the 
time.  Personally the GNU extensions to everything feels like a move 
Microsoft would do, just breaking enough compatibility to create vendor 
lock in.

Thanks,
Travis



More information about the Digitalmars-d mailing list