Platform Independence

September 11, 2008

Platform-independence is something which everyone aspires to when writing code (I hope) but is often one of the first things to go out of the window when time pressures come into play. In the process of preparing the LCFG build tools Perl modules for upload to CPAN I’ve been modifying various chunks to be more platform-agnostic. In particular I’ve been focussing on the file and directory name handling, it’s not that we need the code to work on Windows right now but it’s much more likely to happen at some point in the future if we start out as we mean to go on. When the code was first written I thought it was easiest to just use these sort of idioms:

my $fullpath = join '/', $dirname, $filename;

my @parts = split /\//, $fullpath;
my $file = pop @parts;

It turns out that by ignoring platform-independence I didn’t get all the advantages of excellent modules like File::Spec and File::Basename. For example:

my $fullpath = File::Spec->catfile( $dirname, $filename );

my ($volume,$directories,$file) = File::Spec->splitpath( $path );

I think that code like that is clearer and it is platform-independent without any further effort.

One thing I’ve needed several times is the ability to take two paths and find one as relative to the other. First thoughts might suggest this is simple but I ended up with several different solutions involving regular expressions which coped with them being absolute or relative to begin with. Whilst poking around the perldoc for File::Spec today I noticed:

         Takes a destination path and an optional base path returns a relative
         path from the base path to the destination path:

             $rel_path = File::Spec->abs2rel( $path ) ;
             $rel_path = File::Spec->abs2rel( $path, $base ) ;

         If $base is not present or ’’, then Cwd::cwd() is used. If $base is
         relative, then it is converted to absolute form using "rel2abs()".
         This means that it is taken to be relative to Cwd::cwd().

         On systems with the concept of volume, if $path and $base appear to
         be on two different volumes, we will not attempt to resolve the two
         paths, and we will instead simply return $path.  Note that previous
         versions of this module ignored the volume of $base, which resulted
         in garbage results part of the time.

That’s exactly what I need and it handles all the cases I need. The code can now be simplified and clarified and only by thinking about platform-independence did I actually discover that function.


September 11, 2008

The plan for the new LCFG build tools has always been that they should be packaged as “standard” Perl modules. The idea being that this should help people who want to port LCFG to new platforms or just work on platforms other than those directly supported. A direct consequence of this is that they can be uploaded to the Comprehensive Perl Archive Network (CPAN) which vastly improves distribution of the software. Putting Perl modules onto CPAN means they can be easily converted into RPMs using cpanspec, Debian packages using dh-make-perl or just installed directly using the CPAN shell which is shipped as part of the standard perl distribution. I’ve now uploaded most of the build tools packages, only LCFG::Build::Tools is still to go, here’s the links: