# New Ticket Created by James Keenan # Please include the string: [perl #48459] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=48459 >
The patch attached proposes to refactor Parrot configuration step class inter::progs into two classes: inter::compiler and inter::progs. inter::compiler will search for a C compiler, process any --cc option set on the command line and, if interactive configuration has been requested via command-line option --ask, prompt the user for the location of the desired C compiler. It will then conduct a basic test of that compiler's functioning. If interactive configuration has been requested, this step will print the introductory information currently printed by inter::progs. inter::progs will process all the other compiler-related settings currently done in inter::progs. Only the --cc-related code and the introductory explanation have been extracted. inter::compiler has been refactored so that, in the two new test files found in the patch, we can thoroughly test the Perl 5 aspects of the code while steering clear of the test of the C compiler, which is outside the scope of these tests. This refactoring *may* get us closer to resolving the problem reported by Andy Dougherty in https://rt.perl.org/rt3/Ticket/ Display.html?id=47393. Please review. Thank you very much.
Index: MANIFEST =================================================================== --- MANIFEST (revision 23722) +++ MANIFEST (working copy) @@ -1,7 +1,7 @@ # ex: set ro: # $Id$ # -# generated by tools/dev/mk_manifest_and_skip.pl Mon Dec 10 18:59:19 2007 UT +# generated by tools/dev/mk_manifest_and_skip.pl Tue Dec 11 03:48:56 2007 UT # # See tools/dev/install_files.pl for documentation on the # format of this file. @@ -385,6 +385,7 @@ config/init/miniparrot.pm [] config/init/optimize.pm [] config/inter/charset.pm [] +config/inter/compiler.pm [] config/inter/encoding.pm [] config/inter/lex.pm [] config/inter/libparrot.pm [] @@ -3033,6 +3034,8 @@ t/configure/105-init_hints-03.t [] t/configure/105-init_hints-04.t [] t/configure/106-init_headers.t [] +t/configure/107-inter_compiler-01.t [] +t/configure/107-inter_compiler-02.t [] t/configure/107-inter_progs-01.t [] t/configure/107-inter_progs-02.t [] t/configure/107-inter_progs-03.t [] Index: lib/Parrot/Configure/Step/List.pm =================================================================== --- lib/Parrot/Configure/Step/List.pm (revision 23722) +++ lib/Parrot/Configure/Step/List.pm (working copy) @@ -14,6 +14,7 @@ init::miniparrot init::hints init::headers + inter::compiler inter::progs inter::make inter::lex Index: t/configure/107-inter_progs-03.t =================================================================== --- t/configure/107-inter_progs-03.t (revision 23722) +++ t/configure/107-inter_progs-03.t (working copy) @@ -58,7 +58,6 @@ my ( @prompts, $object ); foreach my $p ( qw| - cc link ld ccflags Index: t/configure/107-inter_progs-04.t =================================================================== --- t/configure/107-inter_progs-04.t (revision 23722) +++ t/configure/107-inter_progs-04.t (working copy) @@ -58,7 +58,6 @@ my ( @prompts, $object ); foreach my $p ( qw| - cc link ld ccflags Index: t/configure/107-inter_progs-01.t =================================================================== --- t/configure/107-inter_progs-01.t (revision 23722) +++ t/configure/107-inter_progs-01.t (working copy) @@ -59,7 +59,6 @@ my ( @prompts, $object ); foreach my $p ( qw| - cc link ld ccflags Index: t/configure/107-inter_compiler-01.t =================================================================== --- t/configure/107-inter_compiler-01.t (revision 0) +++ t/configure/107-inter_compiler-01.t (revision 0) @@ -0,0 +1,135 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# 107-inter_compiler-01.t + +use strict; +use warnings; + +use Test::More tests => 24; +use Carp; +use Data::Dumper; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::init::install'); +use_ok('config::init::hints'); +use_ok('config::inter::compiler'); +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); +use Parrot::IO::Capture::Mini; + +my $args = process_options( + { + argv => [], + mode => q{configure}, + } +); + +my $conf = Parrot::Configure->new; + +test_step_thru_runstep( $conf, q{init::defaults}, $args ); +test_step_thru_runstep( $conf, q{init::install}, $args ); +test_step_thru_runstep( $conf, q{init::hints}, $args ); + +my ( $task, $step_name, $step, $ret ); +my $pkg = q{inter::compiler}; + +$conf->add_steps($pkg); +$conf->options->set( %{$args} ); + +$task = $conf->steps->[3]; +$step_name = $task->step; + +$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" ); + +my $ask; +{ + my $tie_out = tie *STDOUT, "Parrot::IO::Capture::Mini" + or croak "Unable to tie"; + my $ask = inter::compiler::_introduce_interactive_steps($conf); + ok(! defined $ask, "No interactive configuration requested"); + ok(! $tie_out->READLINE, "No verbose or interactive output");; +} +untie *STDOUT; + +$conf->data->set( cc => q{foobar} ); +$conf = inter::compiler::_prompt_for_cc($conf, $ask); +is($conf->data->get('cc'), q{foobar}, + "Value for C compiler correctly detected"); + +#my ( @prompts, $object ); +#foreach my $p ( +# qw| +# cc +# link +# ld +# ccflags +# linkflags +# ldflags +# libs +# cxx +# | +# ) +#{ +# push @prompts, $conf->data->get($p); +#} +#push @prompts, q{y}; +# +#$object = tie *STDIN, 'Tie::Filehandle::Preempt::Stdin', @prompts; +#can_ok( 'Tie::Filehandle::Preempt::Stdin', ('READLINE') ); +#isa_ok( $object, 'Tie::Filehandle::Preempt::Stdin' ); +# +#{ +# open STDOUT, '>', "/dev/null" or croak "Unable to open to myout"; +# $ret = $step->runstep($conf); +# close STDOUT or croak "Unable to close after myout"; +# ok( defined $ret, "$step_name runstep() returned defined value" ); +#} +# +#$object = undef; +#untie *STDIN; + +pass("Keep Devel::Cover happy"); +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +107-inter_compiler-01.t - test config::inter::compiler + +=head1 SYNOPSIS + + % prove t/configure/107-inter_compiler-01.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test Perl 5 aspects of config::inter::compiler, +specifically, the case where neither the C<--verbose> nor the C<--ask> +option is supplied. + +B<Note:> Testing whether the chosen C compiler works or not is outside +the scope of these tests. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::inter::compiler, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: Property changes on: t/configure/107-inter_compiler-01.t ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Index: t/configure/107-inter_progs-02.t =================================================================== --- t/configure/107-inter_progs-02.t (revision 23722) +++ t/configure/107-inter_progs-02.t (working copy) @@ -58,7 +58,6 @@ my ( @prompts, $object ); foreach my $p ( qw| - cc link ld ccflags Index: t/configure/107-inter_compiler-02.t =================================================================== --- t/configure/107-inter_compiler-02.t (revision 0) +++ t/configure/107-inter_compiler-02.t (revision 0) @@ -0,0 +1,122 @@ +#! perl +# Copyright (C) 2007, The Perl Foundation. +# $Id$ +# 107-inter_compiler-02.t + +use strict; +use warnings; + +use Test::More qw(no_plan); # tests => 27; +use Carp; +use Data::Dumper; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::init::install'); +use_ok('config::init::hints'); +use_ok('config::inter::compiler'); +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( test_step_thru_runstep); +use Tie::Filehandle::Preempt::Stdin; +use Parrot::IO::Capture::Mini; + +my $args = process_options( + { + argv => [ q{--ask}, q{--cc=foobar} ], + mode => q{configure}, + } +); + +my $conf = Parrot::Configure->new; + +test_step_thru_runstep( $conf, q{init::defaults}, $args ); +test_step_thru_runstep( $conf, q{init::install}, $args ); +test_step_thru_runstep( $conf, q{init::hints}, $args ); + +my ( $task, $step_name, $step, $ret ); +my $pkg = q{inter::compiler}; + +$conf->add_steps($pkg); +$conf->options->set( %{$args} ); + +$task = $conf->steps->[3]; +$step_name = $task->step; + +$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($conf->options->get('ask'), "--ask option was set"); +my $ask; +{ + my $tie_out = tie *STDOUT, "Parrot::IO::Capture::Mini" + or croak "Unable to tie"; + $ask = inter::compiler::_introduce_interactive_steps($conf); + ok(defined $ask, "Interactive configuration requested"); + my @lines = $tie_out->READLINE; + my $bigstr = join("\n" => @lines); + like($bigstr, + qr/Okay,\sI'm\sgoing\sto\sstart\sby\sasking/s, + "Got introduction to interactive steps" + ); + +} +untie *STDOUT; + +my ( @prompts, $object ); +push @prompts, q{baz}; + +$object = tie *STDIN, 'Tie::Filehandle::Preempt::Stdin', @prompts; +can_ok( 'Tie::Filehandle::Preempt::Stdin', ('READLINE') ); +isa_ok( $object, 'Tie::Filehandle::Preempt::Stdin' ); +{ + open STDOUT, '>', "/dev/null" or croak "Unable to open to myout"; + $conf = inter::compiler::_prompt_for_cc($conf, $ask); + close STDOUT or croak "Unable to close after myout"; + is($conf->data->get('cc'), q{baz}, + "Selection for C compiler correctly detected"); +} +$object = undef; +untie *STDIN; + +pass("Keep Devel::Cover happy"); +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +107-inter_compiler-02.t - test config::inter::compiler + +=head1 SYNOPSIS + + % prove t/configure/107-inter_compiler-02.t + +=head1 DESCRIPTION + +The files in this directory test functionality used by F<Configure.pl>. + +The tests in this file test Perl 5 aspects of config::inter::compiler, +specifically, the case where the C<--ask> option and a value for the +<--cc> option have been supplied. + +B<Note:> Testing whether the chosen C compiler works or not is outside +the scope of these tests. + +=head1 AUTHOR + +James E Keenan + +=head1 SEE ALSO + +config::inter::compiler, F<Configure.pl>. + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: Property changes on: t/configure/107-inter_compiler-02.t ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native Index: config/inter/progs.pm =================================================================== --- config/inter/progs.pm (revision 23722) +++ config/inter/progs.pm (working copy) @@ -3,11 +3,11 @@ =head1 NAME -config/inter/progs.pm - C Compiler and Linker +config/inter/progs.pm - C Linker =head1 DESCRIPTION -Asks the user which compiler, linker, shared library builder, C libraries, +Asks the user which linker, shared library builder, C libraries, lexical analyzer generator and parser generator to use. Also whether debugging should be enabled. @@ -26,8 +26,8 @@ sub _init { my $self = shift; my %data; - $data{description} = q{Determining what C compiler and linker to use}; - $data{args} = [ qw( ask cc cxx link ld ccflags ccwarn linkflags ldflags libs debugging lex yacc maintainer ) ]; + $data{description} = q{Determining what C linker to use}; + $data{args} = [ qw( ask cxx link ld ccflags ccwarn linkflags ldflags libs debugging lex yacc maintainer ) ]; $data{result} = q{}; return \%data; } @@ -36,32 +36,14 @@ my ( $self, $conf ) = @_; my $verbose = $conf->options->get('verbose'); - print "\n" if $verbose; - my ( $cc, $cxx, $link, $ld, $ccflags, $ccwarn, $linkflags, $ldflags, $libs, $lex, $yacc ); + my ( $cxx, $link, $ld, $ccflags, $ccwarn, $linkflags, $ldflags, $libs, $lex, $yacc ); my $ask = $conf->options->get('ask'); - if ($ask) { - print <<'END'; - - Okay, I'm going to start by asking you a couple questions about your - compiler and linker. Default values are in square brackets; you can - hit ENTER to accept them. If you don't understand a question, the - default will usually work--they've been intuited from your Perl 5 - configuration. - -END - } - # Set each variable individually so that hints files can use them as # triggers to help pick the correct defaults for later answers. - $cc = integrate( $conf->data->get('cc'), $conf->options->get('cc') ); - $cc = prompt( "What C compiler do you want to use?", $cc ) - if $ask; - $conf->data->set( cc => $cc ); - $link = integrate( $conf->data->get('link'), $conf->options->get('link') ); $link = prompt( "How about your linker?", $link ) if $ask; $conf->data->set( link => $link ); @@ -127,33 +109,9 @@ $ccwarn = integrate( $conf->data->get('ccwarn'), $conf->options->get('ccwarn') ); $conf->data->set( ccwarn => $ccwarn ); - test_compiler($cc); - return 1; } -sub test_compiler { - my $cc = shift; - - open( my $out_fh, '>', 'test.c' ) or die "Unable to open 'test.c': [EMAIL PROTECTED]"; - print {$out_fh} <<END_C; -int main() { - return 0; -} -END_C - close $out_fh; - - unless ( eval { cc_build(); 1 } ) { - warn "Compilation failed with '$cc'\n"; - exit 1; - } - - unless ( eval { cc_run(); 1 } ) { - warn $@ if $@; - exit 1; - } -} - 1; # Local Variables: Index: config/inter/compiler.pm =================================================================== --- config/inter/compiler.pm (revision 0) +++ config/inter/compiler.pm (revision 0) @@ -0,0 +1,99 @@ +# Copyright (C) 2001-2007, The Perl Foundation. +# $Id$ + +=head1 NAME + +config/inter/compiler.pm - Locate, choose and test a C compiler + +=head1 DESCRIPTION + +Asks the user which compiler to use, then tests that that compiler is +functional. + +=cut + +package inter::compiler; + +use strict; +use warnings; + +use base qw(Parrot::Configure::Step::Base); + +use Parrot::Configure::Step ':inter', ':auto'; + + +sub _init { + my $self = shift; + my %data; + $data{description} = q{Determining what C compiler to use}; + $data{args} = [ qw( ask cc ) ]; + $data{result} = q{}; + return \%data; +} + +sub runstep { + my ( $self, $conf ) = @_; + my $ask = _introduce_interactive_steps($conf); + $conf = _prompt_for_cc($conf, $ask); + test_compiler( $conf->data->get('cc') ); + return 1; +} + +sub _introduce_interactive_steps { + my $conf = shift; + + my $ask = $conf->options->get('ask'); + if ($ask) { + print <<'END'; + + + Okay, I'm going to start by asking you a couple questions about your + compiler and linker. Default values are in square brackets; you can + hit ENTER to accept them. If you don't understand a question, the + default will usually work--they've been intuited from your Perl 5 + configuration. + +END + } + return $ask; +} + +sub _prompt_for_cc { + my ($conf, $ask) = @_; + my $cc = integrate( $conf->data->get('cc'), $conf->options->get('cc') ); + $cc = prompt( "What C compiler do you want to use?", $cc ) + if $ask; + $conf->data->set( cc => $cc ); + return $conf; +} + +sub test_compiler { + my $cc = shift; + + open( my $out_fh, '>', 'test.c' ) or die "Unable to open 'test.c': [EMAIL PROTECTED]"; + print {$out_fh} <<END_C; +int main() { + return 0; +} +END_C + close $out_fh; + + unless ( eval { cc_build(); 1 } ) { + warn "Compilation failed with '$cc'\n"; + exit 1; + } + + unless ( eval { cc_run(); 1 } ) { + warn $@ if $@; + exit 1; + } +} + +1; + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: Property changes on: config/inter/compiler.pm ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native