On Fri, Nov 27, 2009 at 02:24:53PM +0800, Sergey Aleynikov wrote: > Hello, > > I'm just entering automated perl testing, so have a question related > to this topic. I want to test as much possible combinations as > possible on a single machine, > but there's no glue what really matters and what - not. So, currently > i've chosen pairs mymalloc/nothreads and nomymalloc/threaded for perls > 5.8.8, 5.8.9, 5.10.1, 5.11.2, on > i386 and amd64 Freebsd systems. But, is this a correct choice? > Shouldn't i, for example, add 64-bit-int options to any of theese > configs, or make new triplets (so, varying 3 params)? > > Probably, this should go to a new section of testing faq?
I'm not going to address the question directly as Andreas gave a good answer. This post, and Andreas's answer, did remind me to post my build-perl-variants script that I've used to generate automate the creation of multiple perl variants for testing (NYTProf etc). Currently it build variants of these config values: usemymalloc DEBUGGING usemultiplicity uselongdouble useshrplib usethreads use64bitall. With just that set it creates 128 perl builds! Add one more, like -Dmad, and you'll get 256 perl builds. Andreas's point should be clear! On the other hand, I have found it useful. I've meant to add command line options to enable building with a subset of config values (i.e. "exclude uselongdouble & use64bitall" and "only use usethreads & useshrplib & debugging") but haven't got round to it yet -- I just hack the source instead :) If anyone hacks on this please send the patches to me. Perhaps it'll get added to the perl distribution one day. Tim.
#!/usr/bin/env perl use strict; use warnings; =head1 NAME build-perl-variants - build, optionally test, and install multiple variants of perl =head1 SYNOPSIS build-perl-variants [options] root_dir For example: $ cd perl-5.11.1 $ build-perl-variants ~/myperls ... a long time passes ... $ ls ~/myperls perl-5.11.1-debug-longdouble-noshrplib-nothreads perl-5.11.1-nodebug-longdouble-noshrplib-nothreads perl-5.11.1-debug-longdouble-noshrplib-threads perl-5.11.1-nodebug-longdouble-noshrplib-threads perl-5.11.1-debug-longdouble-shrplib-nothreads perl-5.11.1-nodebug-longdouble-shrplib-threads perl-5.11.1-debug-nolongdouble-noshrplib-nothreads perl-5.11.1-nodebug-nolongdouble-noshrplib-nothreads perl-5.11.1-debug-nolongdouble-shrplib-nothreads perl-5.11.1-nodebug-nolongdouble-noshrplib-threads perl-5.11.1-debug-nolongdouble-shrplib-threads perl-5.11.1-nodebug-nolongdouble-shrplib-nothreads =head1 DESCRIPTION This utility is designed to make it easy to build and install multiple variant configurations of a single perl version for testing. It knows about a small set of the possible configuation options: usethreads usemultiplicity useshrplib use64bitall uselongdouble usemymalloc DEBUGGING By default all options are included in the set from which all the combinations are calculated. Since the goal is testing it errs on the side of caution: to be immune from defaults it uses C<-Ufoo> to disable the options that aren't being enabled, and it installs the perls into unambiguously named directories. =head1 TODO Add way to pass extra options, like -Dusedevel -Uversiononly Provide a way to specify variants to include or exclude. Detect Ctrl-C and kill off the builds. It doesn't work at the moment. =head2 Other Ideas Do an initial trial Configure run and parse the generated config.sh to determine what variants can't be built on this platform and eliminate them from the trial set. =head1 AUTHOR Tim Bunce. =head1 COPYRIGHT Copyright (c) 1994-2009 Tim Bunce. Ireland. All rights reserved. You may distribute under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl 5.10.0 README file. =cut use Getopt::Long qw(:config require_order); use Cwd; use Data::Dumper; my %all_variants = ( usethreads => {}, usemultiplicity => {}, useshrplib => {}, use64bitall => {}, uselongdouble => {}, usemymalloc => {}, DEBUGGING => { tag => 'debug' }, ); GetOptions( 'name=s' => \my $opt_name, # eg myperl-x.y.z 'only=s' => \my $opt_only, # only build variants matching this regex 'skip=s' => \my $opt_skip, # don't build variants matching this regex 'test!' => \(my $opt_test = 1), # run make test, --notest to disable 'jobs=i' => \(my $opt_jobs = 3), # for $ENV{TEST_JOBS} 'n!' => \my $opt_n, # just list, don't act ) or exit 1; my $root = shift or die "No installation root directory specified\n"; -w $root or mkdir($root, 0711) or die "Can't create installation root directory '$root': $!\n"; $opt_name ||= do { if (open my $fh, '<', 'patchlevel.h') { my %patchlevel; while (<$fh>) { $patchlevel{$1} = $2 if m/define \s+ (\w+) \s+ (\d+)/x; } "perl-" . join ".", @patchlevel{qw(PERL_REVISION PERL_VERSION PERL_SUBVERSION)}; } elsif ($opt_n) { "perl-" . join ".", 0, 0, 0; } else { die "Can't open patchlevel.h: $!"; } }; my @build_variants = keys %all_variants; @build_variants = grep { /$opt_only/ } @build_variants if $opt_only; @build_variants = grep { !/$opt_skip/ } @build_variants if $opt_skip; # XXX this doesn't seem able to stop the charging hurd of nested makes $ENV{PERL_SIGNALS} = 'unsafe'; my $aborted = 0; sub catch_sigint { $aborted++; die "Aborted" }; use POSIX qw(SIGINT); POSIX::sigaction(SIGINT, POSIX::SigAction->new(\&catch_sigint)) or do { warn "Error setting SIGINT handler: $!\n"; $SIG{INT} = \&catch_sigint; }; my $powerset = powerset(@build_variants); printf "Building %d variants using combinations of: %s\n", scalar @$powerset, "@build_variants"; my %status; foreach my $set (@$powerset) { my %enabled = map { $_=>1 } @$set; my %option_state = map { $_ => ($enabled{$_}) ? 1 : 0 } @build_variants; my @options; my $tag = ''; while ( my ($option, $enabled) = each %option_state ) { my $opt = $all_variants{$option}{tag} || do { $option =~ m/^use(.*)/ ? $1 : $option }; if ($enabled) { push @options, "-D$option"; $tag .= "-$opt"; } else { push @options, "-U$option"; $tag .= "-no$opt"; } } eval { warn "*** Building $opt_name$tag\n"; build_a_perl_variant($tag, \...@options); warn "\n"; } unless $opt_n; $status{"$opt_name$tag"} = $@; last if $aborted; } foreach my $tag (sort keys %status) { printf "%s: %s\n", $tag, $status{$tag} || 'ok'; } exit 0; sub build_a_perl_variant { my ($tag, $options) = @_; my $name = "$opt_name$tag"; my $prefix = "$root/$name"; my $logfile = "build$tag.log"; my $logit = ">> $logfile 2>&1"; unlink $logfile; run("make distclean > /dev/null 2>&1 || true") if -f "Makefile"; run("./Configure -des @$options -Dusedevel -Dprefix=$prefix $logit"); run("make $logit"); if ($opt_test) { local $ENV{TEST_JOBS} = $opt_jobs if $opt_jobs; run("make test $logit") if $opt_test; } # just install perl, not the docs run("make install.perl $logit"); } sub run { my ($cmd) = @_; die "Aborted\n" if $aborted; warn "\t$cmd\n"; system($cmd) == 0 or die "ERROR status returned from $cmd\n"; } # mjd's powerset implementation. See http://perl.plover.com/LOD/199803.html # And http://search.cpan.org/perldoc?List::PowerSet sub powerset { return [[]] if @_ == 0; my $first = shift; my $pow = &powerset; [ map { [$first, @$_ ], [ @$_] } @$pow ]; }