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