buildperl.pl

BooK on 2009-10-29T20:44:04

I'm trying to compile a bunch of old perls to test my modules against them. I started with 5.8.9, and it went like this:

    $ git checkout -f perl-5.8.9
    [git output]
    $ git clean -xdf
    [more git output]
    $ sh Configure -Dprefix=/opt/perl/5.8.9 -des -Uinstallusrbinperl
    [Configure output]
    $ make && make test && make install
    [make output]
    [test output]
    [install output]

And, ta-da! After less than 15 minutes, Perl 5.8.9 was in /opt/perl/, ready to be used.

Encouraged by this, I went on to compile 5.8.8. I was a bit disappointed when the same procedure (after a s/5.8.8/5.8.9/g) failed with:

    $ sh Configure -Dprefix=/opt/perl/5.8.8 -des -Uinstallusrbinperl
    [Configure output]
    Run make depend now? [y]
    sh ./makedepend MAKE=make
    make[1]: Entering directory `/data/home/book/src/ext/perl'
    sh writemain lib/auto/DynaLoader/DynaLoader.a  > perlmain.c
    rm -f opmini.c
    cp op.c opmini.c
    echo  av.c scope.c op.c doop.c doio.c dump.c hv.c mg.c reentr.c perl.c perly.c pp.c pp_hot.c pp_ctl.c pp_sys.c regcomp.c regexec.c utf8.c gv.c sv.c taint.c toke.c util.c deb.c run.c universal.c xsutils.c pad.c globals.c perlio.c perlapi.c numeric.c locale.c pp_pack.c pp_sort.c miniperlmain.c perlmain.c opmini.c | tr ' ' '\n' >.clist
    make[1]: Leaving directory `/data/home/book/src/ext/perl'
    ./makedepend: 1: Syntax error: Unterminated quoted string
    make: *** [depend] Error 2

    If you compile perl5 on a different machine or from a different object
    directory, copy the Policy.sh file from this object directory to the
    new one before you run Configure -- this will help you with most of
    the policy defaults.

In the past, I had tried to compile older Perls, and Sébastien Aperghis-Tramoni had pointed me to a few patches he had made to be able to compile 5.004_05 with a more recent (3.x) gcc.

So, by looking at his patch again and the output of git diff perl-5.8.8 perl-5.8.9 -- makedepend.SH I was able to produce a patch, that looked exactaly like Sébastien's patches for 5.004_05. The Configure step now worked!

But then it's the compilation phase that failed:

    $ make
    [make output]
        Making IPC::SysV (dynamic)
    Checking if your kit is complete...
    Looks good
    Writing Makefile for IPC::SysV
    make[1]: Entering directory `/data/home/book/src/ext/perl/ext/IPC/SysV'
    make[1]: Leaving directory `/data/home/book/src/ext/perl/ext/IPC/SysV'
    make[1]: Entering directory `/data/home/book/src/ext/perl/ext/IPC/SysV'
    cp Msg.pm ../../../lib/IPC/Msg.pm
    cp Semaphore.pm ../../../lib/IPC/Semaphore.pm
    cp SysV.pm ../../../lib/IPC/SysV.pm
    ../../../miniperl "-I../../../lib" "-I../../../lib" ../../../lib/ExtUtils/xsubpp  -typemap ../../../lib/ExtUtils/typemap  SysV.xs > SysV.xsc && mv SysV.xsc SysV.c
    cc -c   -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2   -DVERSION=\"1.04\" -DXS_VERSION=\"1.04\" -fpic "-I../../.."   SysV.c
    SysV.xs:7:25: error: asm/page.h: No such file or directory
    make[1]: *** [SysV.o] Error 1
    make[1]: Leaving directory `/data/home/book/src/ext/perl/ext/IPC/SysV'
    make: *** [lib/auto/IPC/SysV/SysV.so] Error 2

This looked a bit trickier. Luckily, Google informed me that the asm/page.h file had moved in the Linux tree. Using git again, I looked for changes involving page.h. The changes were a lot bigger, and harder for me to understand.

By chance, the first interesting diff I found was for a change in ext/Devel/PPPort/devel/buildperl.pl. Wow, this looked exactly like the tool I needed to, erm, build perl.

So instead of adding complexity to my home-made perl-building script by adding more cases where a patch was necessary, I tried my hand at patching buildperl.pl to make it support newer gcc versions than the ones that existed at the time the older perls were written.

Looking for the proper patches with git is extremely easy, and I was quickly able to find the necessary patches. The longer part was to actually compile all Perls from 5.6.0 to 5.9.5. :-)

Since buildperl.pl works with perl archives, my test script ended up like this:

    #!/bin/sh

    # blead has my local patch
    git checkout blead
    git clean -xdf

    # setup temporary directories
    rm /tmp/buildperl.log
    rm -rf /tmp/perl
    mkdir /tmp/perl
    mkdir /tmp/perl/source

    # compile and test all the tags given on command-line
    for tag in $* ; do

        # get the version
        version=`echo $tag|cut -d- -f 2`

        # make a tarball
        echo "=== creating /tmp/perl/source/perl-$version.tar.gz"
        git archive --format=tar --prefix=$tag/ $tag^{tree} \
        | gzip > /tmp/perl/source/$tag.tar.gz

        perl cpan/Devel-PPPort/devel/buildperl.pl --config default --perl $version --test

        # check it was installed correctly
        if [ -d /tmp/perl/install/default/$tag/ ] ; then
            result="ok"
        else
            result="not ok"
        fi
        echo "$result - $version" >> /tmp/buildperl.log

    done

Then I just fed it with the appropriate git tags, and let it run for a while:

    $ ./compile_perl `git tag -l 'perl-5.8*'`

So within one and a half hour, I was able to compile, test and install all the 5.8.x versions of Perl.

I already have added the changes that allow 5.6.x, 5.8.x and 5.9.x to compile again in modern environments, and just sent the patches to P5P and Marcus Holland-Moritz.

Eventually, I'll work on adding the needed patches for versions 5.004, 5.005, and send another patch batch.


Maint branches on my github

dagolden on 2009-10-30T00:57:26

FWIW, I've done similar work in the past and published it on my github clone of the perl repository:

git://github.com/dagolden/perl.git

Relevant branches are:

maint-5.6.2
maint-5.8.0
maint-5.8.1
maint-5.8.2
maint-5.8.3
maint-5.8.4
maint-5.8.5
maint-5.8.6
maint-5.8.7
maint-5.8.8

Hope that helps others looking to build old versions of Perl.

-- David