Module::Build with XS

September 30, 2008

This is mainly for my own future benefit. It has just taken me ages to discover how to build Perl modules using Module::Build when parts of the module are done with XS.

The Build.PL needs to contain:

    extra_compiler_flags => ['-Wall'],
    extra_linker_flags => ['-lfoo'],
    include_dirs  => ['.'],

where foo is whatever library you need to link against. The include_dirs specifies where to find the ppport.h file. Also, the build-requires must be like:

    build_requires => {
        'ExtUtils::CBuilder' => 0,

Finally, unlike the old MakeMaker, XS modules should go in the right place in the lib/ tree, e.g. Foo::Bar should be lib/Foo/Bar.xs, there will probably also be a lib/Foo/ already in that directory.

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:

Cat-A-Moose Part II

September 9, 2008

Way back in June I posted a link to an article discussing how the Catalyst guys were looking at porting the framework to Moose. There is now a follow-up article which covers their progress so far.

I continue to find this work very encouraging, it is likely to drive development of Moose to make it much faster and Catalyst desperately needs some reworking of the API to use something like Moose to make it much cleaner.

Eating your own dog food

September 5, 2008

I’m currently reading “Practices of an Agile Developer” which is part of the “Pragmatic Programmers” series of books. It contains many great ideas and tips on how to be a better software developer and is an excellent followup to the original, and now almost iconic, “Pragmatic Programmer” book.

When I’ve finished I’ll put up a full review. For now I thought it worth noting one point which caught my attention, the idea of “eating your own dog food”. As you can see from the wikipedia article, this is not a new idea.

This is something that I’ve been attempting to put into practice throughout the LCFG buildtools project. As soon as the tools I developed became capable of actually managing the releasing and packaging of software projects I’ve been using them to do just that with the new buildtools packages. At times I’ve wondered if the extra effort would be worth it and it has got me into some awkward positions when the tools at hand are broken and putting the fix into place is made more difficult by not being able to do straightforward releases. The big advantage is that by actually using the tools extensively I’ve developed a really good idea of what works and what just sucks. There is no better way to check if the high-level design is correct than to use the system in its infancy. The build tools also have unit tests which will say if an individual piece of code does the right thing according to some specification but they will never be useful for judging whether a tool “feels right”. This has undoubtedly led to the new tools being much better equipped for building software packages for projects which are not LCFG components, that’s not to say that the packaging of LCFG components has been in anyway ignored, of course. In a way this has also provided a form of continuous integration testing, I’ve typically needed the latest submitted version of the tools to be working in some form at all times to get onto the next stage.

I think it’s clear that taking an “agile” approach has been much better than the more traditional methodology of doing all the design up-front, coding up the design and only then doing full usability testing. Up-front planning is absolutely essential but I think it needs to be kept to a high enough level to make it possible to see how the development can be split into chunks, each focussing on separate pieces of functionality. For example, I first worked on being able to use the tools to tag releases, once that was working I started using it and moved onto adding support for packaging. At the beginning of each chunk that work is planned in more depth and, if necessary, prototypes are developed to test ideas before full development commences.

One for the Perl geeks

September 4, 2008

When writing a Perl module to wrap various CVS functionality, no matter how much of a good idea you might think it is, you really don’t want to add a method named “import”. You will get the weirdest error messages when you attempt to “use” the module and you will feel like hitting your head on the wall when it finally dawns on you as to what you have just done…