# New Ticket Created by James Keenan # Please include the string: [perl #47902] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=47902 >
Over the last few weeks Andy Dougherty and chromatic have pointed out some flaws in the logic underlying the tests I have written for the config steps, particular those in t/configure/10?-*.t. We've wrapped some of these in TODO blocks, but I've been trying to think of a better approach. One recurring problem -- though not the only problem -- is the fact that to jump-start its understanding of the state of a user's system, Parrot's Configure.pl relies on the presence of a Perl 5 Config.pm -- and its exported variable %Config -- to perform initial population of many elements in the Parrot::Configure object's internal data structure. This is good enough to start configuration; values supplied by %Config are overwritten as necessary throughout the configuration steps. But it means (a) we're got a global variable running loose in many of our configuration step classes; and (b) different users -- more particularly, different people running the tests -- will get different values depending on *which* %Config they're using: one from a Perl 5 they built themselves; a vendor- supplied Perl 5; etc. In the *long* run (Parrot 2.0, if I understand earlier remarks by Allison correctly), we want to eliminate this dependency on the presence of a working Perl 5 on a user's system. But in the *short* run, if we cannot reduce our dependency on %Config, let's at least confine that dependency to just one of our 60 configuration steps rather than 15 of them, ranging from step #2 to step #60 (the last). The patch attached does that. It confines 'use Config;' to the second configuration step, init::defaults. Any time where a subsequent configuration step currently consults %Config in order to get a value for element X in the Parrot::Configure object, a similar consultation is made in init::defaults and a new element p5Config_X is added to that object. So all the lookups in %Config are made within one step, then assigned to their final values in the other 14 steps which currently 'use Config'. There was one thorny problem I had to overcome in preparing this patch: Determining that, in the 4 instances where the Parrot::Configure::Data::keys() method is used to read the names of elements in the Parrot::Configure object, no 'p5Config_X' elements are read. 'make' is now completing and 'make test' is passing all tests on Linux. Since this patch affects 16 configuration modules, I would like to have it tried out on as many platforms as possible. Reports from Linux and OpenBSD would be particularly helpful, as the init::hints step for these two OSes calls OS-specific modules which had lookups in %Config. Thank you very much. kid51
Index: t/configure/160-gen_config_pm.t =================================================================== --- t/configure/160-gen_config_pm.t (revision 23155) +++ t/configure/160-gen_config_pm.t (working copy) @@ -5,9 +5,10 @@ use strict; use warnings; -use Test::More tests => 2; +use Test::More qw(no_plan); # tests => 11; use Carp; -use lib qw( lib ); +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); use_ok('config::gen::config_pm'); =for hints_for_testing The grand finale! Try to maximize branch @@ -15,6 +16,36 @@ =cut +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); + +my $args = process_options( { + argv => [], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); + +my ($task, $step_name, @step_params, $step, $ret); +my $pkg = q{gen::config_pm}; + +$conf->add_steps($pkg); +$conf->options->set(%{$args}); +$task = $conf->steps->[1]; +$step_name = $task->step; [EMAIL PROTECTED] = @{ $task->params }; + +$step = $step_name->new(); +ok(defined $step, "$step_name constructor returned defined value"); +isa_ok($step, $step_name); +ok($step->description(), "$step_name has description"); + +# ok($step->runstep($conf), "runstep() returned true value"); + +pass("Keep Devel::Cover happy"); pass("Completed all tests in $0"); ################### DOCUMENTATION ################### Index: t/configure/125-auto_headers-04.t =================================================================== --- t/configure/125-auto_headers-04.t (revision 23155) +++ t/configure/125-auto_headers-04.t (working copy) @@ -5,7 +5,7 @@ use strict; use warnings; -use Test::More tests => 15; +use Test::More tests => 14; use Carp; use Config; use lib qw( lib t/configure/testlib ); @@ -42,8 +42,7 @@ isa_ok( $step, $step_name ); ok( $step->description(), "$step_name has description" ); -auto::headers::_set_from_Config($conf, \%Config); -ok($conf->data->get('i_netinetin'), "Mapping made correctly"); +auto::headers::_set_from_Config($conf); ok(! $conf->data->get('i_niin'), "Mapping made correctly"); { Index: t/configure/102-init_defaults-01.t =================================================================== --- t/configure/102-init_defaults-01.t (revision 23155) +++ t/configure/102-init_defaults-01.t (working copy) @@ -7,7 +7,6 @@ use warnings; use Test::More tests => 6; use Carp; -use Data::Dumper; use lib qw( lib ); use_ok('config::init::defaults'); use Parrot::Configure; Index: t/configure/125-auto_headers-01.t =================================================================== --- t/configure/125-auto_headers-01.t (revision 23155) +++ t/configure/125-auto_headers-01.t (working copy) @@ -43,7 +43,6 @@ my $ret = $step->runstep($conf); ok( $ret, "$step_name runstep() returned true value" ); is($step->result(), q{skipped}, "Expected result was set"); - pass("Completed all tests in $0"); ################### DOCUMENTATION ################### Index: config/init/defaults.pm =================================================================== --- config/init/defaults.pm (revision 23155) +++ config/init/defaults.pm (working copy) @@ -41,6 +41,34 @@ sub runstep { my ( $self, $conf ) = @_; + # Later configuration steps need access to values from the Perl 5 + # %Config. However, other later configuration steps may change + # the corresponding values in the Parrot::Configure object. In + # order to provide access to the original values from Perl 5 + # %Config, we grab those settings we need now and store them in + # special keys within the Parrot::Configure object. + # This is a two-stage process. + + # Stage 1: + foreach my $orig ( qw| + archname + ccflags + d_socklen_t + longsize + optimize + osname + sig_name + use64bitint + | ) { + $conf->data->set( qq{p5Config_$orig} => $Config{$orig} ); + } + + # Stage 2 (anticipating needs of config/auto/headers.pm): + $conf->data->set( + map { q|p5Config_| . $_ => $Config{$_} } + grep { /^i_/ } keys %Config + ); + # We need a Glossary somewhere! $conf->data->set( debugging => $conf->options->get('debugging') ? 1 : 0, Index: config/init/hints/openbsd.pm =================================================================== --- config/init/hints/openbsd.pm (revision 23155) +++ config/init/hints/openbsd.pm (working copy) @@ -5,7 +5,6 @@ use strict; use warnings; -use Config; sub runstep { my ( $self, $conf ) = @_; @@ -22,7 +21,7 @@ } $conf->data->set( libs => $libs ); - if ( ( split( m/-/, $Config{archname}, 2 ) )[0] eq 'powerpc' ) { + if ( ( split( m/-/, $conf->data->get('p5Config_archname'), 2 ) )[0] eq 'powerpc' ) { $conf->data->set( as => 'as -mregnames' ); } Index: config/init/hints/linux.pm =================================================================== --- config/init/hints/linux.pm (revision 23155) +++ config/init/hints/linux.pm (working copy) @@ -6,7 +6,7 @@ use strict; use warnings; -use Config; +#use Config; our $verbose; @@ -147,7 +147,9 @@ libparrot_soname => '-Wl,-soname=libparrot$(SHARE_EXT).$(SOVERSION)', ); - if ( ( split( m/-/, $Config{archname}, 2 ) )[0] eq 'ia64' ) { +# if ( ( split( m/-/, $Config{archname}, 2 ) )[0] eq 'ia64' ) { + if ( ( split( m/-/, $conf->data->get('p5Config_archname'), 2 ) )[0] eq 'ia64' ) { + $conf->data->set( platform_asm => 1 ); } return; Index: config/init/optimize.pm =================================================================== --- config/init/optimize.pm (revision 23155) +++ config/init/optimize.pm (working copy) @@ -19,7 +19,7 @@ use base qw(Parrot::Configure::Step::Base); -use Config; +#use Config; use Parrot::Configure::Step; @@ -56,7 +56,8 @@ # use perl5's value # gcc 4.1 doesn't like -mcpu=xx, i.e. it's deprecated - my $opts = $Config{optimize}; +# my $opts = $Config{optimize}; + my $opts = $conf->data->get('p5Config_optimize'); my $gccversion = $conf->data->get( 'gccversion' ); my $arch_opt = 'cpu'; if ( defined $gccversion and $gccversion > 3.3 ) { Index: config/auto/gdbm.pm =================================================================== --- config/auto/gdbm.pm (revision 23155) +++ config/auto/gdbm.pm (working copy) @@ -19,7 +19,7 @@ use base qw(Parrot::Configure::Step::Base); -use Config; +#use Config; use Parrot::Configure::Step ':auto'; @@ -53,7 +53,8 @@ my $linkflags = $conf->data->get('linkflags'); my $ccflags = $conf->data->get('ccflags'); - my $osname = $Config{osname}; +# my $osname = $Config{osname}; + my $osname = $conf->data->get('p5Config_osname'); # On OS X check the presence of the gdbm header in the standard # Fink location. Index: config/auto/socklen_t.pm =================================================================== --- config/auto/socklen_t.pm (revision 23155) +++ config/auto/socklen_t.pm (working copy) @@ -19,7 +19,7 @@ use base qw(Parrot::Configure::Step::Base); -use Config; +#use Config; use Parrot::Configure::Step ':auto'; @@ -44,7 +44,8 @@ sub _probe_for_socklen_t { my $conf = shift; - return $conf->data->get('has_socklen_t') || $Config{d_socklen_t}; +# return $conf->data->get('has_socklen_t') || $Config{d_socklen_t}; + return $conf->data->get('has_socklen_t') || $conf->data->get('p5Config_d_socklen_t'); } sub _evaluate_socklen_t { Index: config/auto/signal.pm =================================================================== --- config/auto/signal.pm (revision 23155) +++ config/auto/signal.pm (working copy) @@ -84,10 +84,11 @@ # Any changes made here will be lost. # EOF - use Config; +# use Config; my ( $i, $name ); $i = 0; - foreach $name ( split( ' ', $Config{sig_name} ) ) { +# foreach $name ( split( ' ', $Config{sig_name} ) ) { + foreach $name ( split( ' ', $conf->data->get('p5Config_sig_name') ) ) { print {$O} ".constant SIG$name\t$i\n" if $i; $i++; } Index: config/auto/pack.pm =================================================================== --- config/auto/pack.pm (revision 23155) +++ config/auto/pack.pm (working copy) @@ -19,7 +19,7 @@ use base qw(Parrot::Configure::Step::Base); use Parrot::Configure::Step; -use Config; +#use Config; sub _init { @@ -47,14 +47,20 @@ my $which = $_ eq 'intvalsize' ? 'packtype_i' : 'packtype_op'; my $size = $conf->data->get($_); my $format; - if ( ( $] >= 5.006 ) && ( $size == $longsize ) && ( $size == $Config{longsize} ) ) { +# if ( ( $] >= 5.006 ) && ( $size == $longsize ) && ( $size == $Config{longsize} ) ) { + if ( + ( $] >= 5.006 ) && + ( $size == $longsize ) && + ( $size == $conf->data->get('p5Config_longsize') ) + ) { $format = 'l!'; } elsif ( $size == 4 ) { $format = 'l'; } - elsif ( $size == 8 || $Config{use64bitint} eq 'define' ) { - +# elsif ( $size == 8 || $Config{use64bitint} eq 'define' ) { + elsif ( $size == 8 || + $conf->data->get('p5Config_use64bitint') eq 'define' ) { # pp_pack is annoying, and this won't work unless sizeof(UV) >= 8 $format = 'q'; } Index: config/auto/m4.pm =================================================================== --- config/auto/m4.pm (revision 23155) +++ config/auto/m4.pm (working copy) @@ -19,7 +19,7 @@ use base qw(Parrot::Configure::Step::Base); -use Config; +#use Config; use Parrot::Configure::Step ':auto', 'capture_output'; @@ -40,7 +40,8 @@ $verbose = $conf->options->get( 'verbose' ); print $/ if $verbose; - my $archname = $Config{archname}; +# my $archname = $Config{archname}; + my $archname = $conf->data->get('p5Config_archname'); my ( $cpuarch, $osname ) = split m/-/, $archname, 2; if ( !defined $osname ) { ( $osname, $cpuarch ) = ( $cpuarch, "" ); Index: config/auto/gmp.pm =================================================================== --- config/auto/gmp.pm (revision 23155) +++ config/auto/gmp.pm (working copy) @@ -18,7 +18,7 @@ use base qw(Parrot::Configure::Step::Base); -use Config; +#use Config; use Parrot::Configure::Step ':auto'; @@ -63,7 +63,8 @@ $conf->data->add( ' ', libs => '-lgmp' ); } - my $osname = $Config{osname}; +# my $osname = $Config{osname}; + my $osname = $conf->data->get('p5Config_osname'); # On OS X check the presence of the gmp header in the standard # Fink location. Index: config/auto/readline.pm =================================================================== --- config/auto/readline.pm (revision 23155) +++ config/auto/readline.pm (working copy) @@ -18,7 +18,7 @@ use base qw(Parrot::Configure::Step::Base); -use Config; +#use Config; use Parrot::Configure::Step ':auto'; @@ -53,7 +53,8 @@ $conf->data->add( ' ', libs => '-lreadline' ); } - my $osname = $Config{osname}; +# my $osname = $Config{osname}; + my $osname = $conf->data->get('p5Config_osname'); # On OS X check the presence of the readline header in the standard # Fink/macports location. Index: config/auto/gcc.pm =================================================================== --- config/auto/gcc.pm (revision 23155) +++ config/auto/gcc.pm (working copy) @@ -362,8 +362,9 @@ next unless $opt; # Ignore blank lines if ( $opt =~ /-mno-accumulate-outgoing-args/ ) { - use Config; - if ( $Config{archname} !~ /86/ ) { +# use Config; +# if ( $Config{archname} !~ /86/ ) { + if ( $conf->data->get('p5Config_archname') !~ /86/ ) { $opt =~ s/-mno-accumulate-outgoing-args//; } } Index: config/auto/alignptrs.pm =================================================================== --- config/auto/alignptrs.pm (revision 23155) +++ config/auto/alignptrs.pm (working copy) @@ -19,7 +19,7 @@ use base qw(Parrot::Configure::Step::Base); use Parrot::Configure::Step ':auto'; -use Config; +#use Config; sub _init { @@ -45,7 +45,8 @@ $align = $conf->data->get('ptr_alignment'); $result_str .= "configured: "; } - elsif ( $^O eq 'hpux' && $Config{ccflags} !~ /DD64/ ) { +# elsif ( $^O eq 'hpux' && $Config{ccflags} !~ /DD64/ ) { + elsif ( $^O eq 'hpux' && $conf->data->get('p5Config_ccflags') !~ /DD64/ ) { # HP-UX 10.20/32 hangs in this test. $align = 4; Index: config/gen/config_h.pm =================================================================== --- config/gen/config_h.pm (revision 23155) +++ config/gen/config_h.pm (working copy) @@ -71,6 +71,7 @@ EOF for ( sort( $conf->data->keys() ) ) { + next if /^p5Config_/; next unless /i_(\w+)/; if ( $conf->data->get($_) ) { print {$HH} "#define PARROT_HAS_HEADER_\U$1 1\n"; @@ -107,6 +108,7 @@ EOF for ( sort( $conf->data->keys() ) ) { + next if /^p5Config_/; next unless /HAS_(\w+)/; if ( $conf->data->get($_) ) { print {$HH} "#define PARROT_HAS_\U$1 1\n"; @@ -120,6 +122,7 @@ EOF for ( sort( $conf->data->keys() ) ) { + next if /^p5Config_/; next unless /D_(\w+)/; my $val; if ( $val = $conf->data->get($_) ) { Index: config/gen/platform.pm =================================================================== --- config/gen/platform.pm (revision 23155) +++ config/gen/platform.pm (working copy) @@ -19,7 +19,7 @@ use base qw(Parrot::Configure::Step::Base); -use Config; +#use Config; use Parrot::Configure::Step qw(copy_if_diff); @@ -43,7 +43,8 @@ $platform = "win32" if $platform =~ /^mingw/; $platform =~ s/^ms//; - if ( ( split m/-/, $Config{archname}, 2 )[0] eq 'ia64' ) { +# if ( ( split m/-/, $Config{archname}, 2 )[0] eq 'ia64' ) { + if ( ( split m/-/, $conf->data->get('p5Config_archname'), 2 )[0] eq 'ia64' ) { $platform = 'ia64'; } Index: config/gen/config_pm.pm =================================================================== --- config/gen/config_pm.pm (revision 23155) +++ config/gen/config_pm.pm (working copy) @@ -38,6 +38,13 @@ $conf->data->clean; + my @p5Config_keys; + foreach my $key (keys %{$conf->data->{c}}) { + my $del = delete $conf->data->{c}->{$key} + if $key =~ /^p5Config_/; + push @p5Config_keys, $del; + } + genfile( 'config/gen/config_pm/myconfig.in', 'myconfig' ); open( my $IN, "<", "config/gen/config_pm/Config_pm.in" )