Please review revised patch attached. Geoff, does this work for you? Jerry, okay on Win32?
(All tests passing on Darwin and Linux.)
Index: lib/Parrot/Configure/Step/Methods.pm =================================================================== --- lib/Parrot/Configure/Step/Methods.pm (revision 27185) +++ lib/Parrot/Configure/Step/Methods.pm (working copy) @@ -4,6 +4,8 @@ package Parrot::Configure::Step::Methods; use strict; use warnings; +use Carp; +use Data::Dumper; =head1 NAME @@ -24,12 +26,10 @@ Since the methods are not part of the public interface, their names should begin with an underscore 'C<_>'. -=head2 Methods +=head1 METHODS -=over 4 +=head2 C<_recheck_settings()> -=item C<_recheck_settings()> - $self->_recheck_settings($conf, $libs, $ccflags, $linkflags, $verbose); Currently used in configuration step classes auto::gmp, auto::readline, @@ -46,7 +46,7 @@ $self->set_result('no'); } -=item C<_handle_darwin_for_fink()> +=head2 C<_handle_darwin_for_fink()> $self->_handle_darwin_for_fink($conf, $libs, $osname, $file); @@ -83,6 +83,21 @@ return 1; } +=head2 C<_handle_darwin_for_macports()> + + $self->_handle_darwin_for_macports($conf, $libs, $osname, $file); + +Currently used in configuration step classes auto::gmp, auto::readline and +auto::opengl. + +Modifies settings for C<linkflags>, C<ldflags> and C<ccflags> in the +Parrot::Configure object's data structure. + +Potentially expandable to cover all BSD-ports systems -- but as yet there has +been no demand. + +=cut + sub _handle_darwin_for_macports { my ($self, $conf, $osname, $file) = @_; if ( $osname =~ /darwin/ ) { @@ -98,8 +113,105 @@ return 1; } +=head2 C<_add_to_libs()> + + $self->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_gcc => '-lalpha32 -lalpha32 -lopenalpha32', + win32_nongcc => 'alpha.lib', + darwin => 'alphadarwin.lib', + default => '-lalpha', + } ); + +B<Purpose>: In a number of configuration step classes, the class's +C<runstep()> method adds libraries to the wordspace-delimited string found in +the Parrot::Configure object's C<libs> attribute. The libraries to be added +are either OS-specific or OS/C-compiler-specific. This method enables the +developer of a configuration step class to define a default value for such a +flag -- usually the value that is appropriate to Unix-like systems -- and, +optionally, to define non-default values for certain OSes or OS/C-compiler +combinations. We currently support settings for: + +=over 4 + +=item * MSWin32 with F<gcc> as the C-compiler. + +=item * MSWin32 with any C-compiler other than F<gcc>. + +=item * Darwin. + =back +B<Arguments>: Reference to a hash. Four of the hash's key-value pairs are +required: + +=over 4 + +=item * C<conf> + +The Parrot::Configure object. Supplied within C<runstep()>. + +=item * C<osname> + +The name of the operating system. Supplied within C<runstep()>. + +=item * C<cc> + +The name of the C-compiler. Supplied within C<runstep()>. + +=item * C<default> + +Libraries to be added where no OS-specific or OS/C-compiler-specific libraries +are to be added. Wordspace-delimited string. + +=back + +These optional settings are currently supported and, if provided, will +supersede the value in C<default>. + +=over 4 + +=item * C<win32_gcc> + +Libraries to be added where OS is mswin32 and C-compiler is F<gcc>. +Wordspace-delimited string. + +=item * C<win32_nongcc> + +Libraries to be added where OS is mswin32 and C-compiler is not F<gcc>. +Wordspace-delimited string. + +=item * C<darwin> + +Libraries to be added where OS is Darwin. Do not supply a value if the value +you need is the same as C<default>. Wordspace-delimited string. + +=back + +B<Return Value>: Returns true value upon success. + +=cut + +sub _add_to_libs { + my $self = shift; + my $args = shift; + croak "_add_to_libs() takes hashref: $!" unless ref($args) eq 'HASH'; + my $platform = + ($args->{osname} =~ /mswin32/i && + $args->{cc} =~ /^gcc/i) ? 'win32_gcc' + : $args->{osname} =~ /mswin32/i ? 'win32_nongcc' + : $args->{osname} =~ /darwin/i ? 'darwin' + : 'default'; + my $libs = defined($args->{$platform}) + ? $args->{$platform} + : $args->{default}; + $args->{conf}->data->add(' ', libs => $libs); + return 1; +} + + =head1 SEE ALSO Parrot::Configure::Step. Index: t/steps/auto_crypto-02.t =================================================================== --- t/steps/auto_crypto-02.t (revision 27185) +++ t/steps/auto_crypto-02.t (working copy) @@ -4,7 +4,7 @@ use strict; use warnings; -use Test::More tests => 19; +use Test::More tests => 25; use Carp; use Cwd; use lib qw( lib t/configure/testlib ); @@ -40,6 +40,57 @@ isa_ok( $step, $step_name ); ok( $step->description(), "$step_name has description" ); +# Mock different OS/compiler combinations. +my ($osname, $cc, $initial_libs); +$initial_libs = $conf->data->get('libs'); +$osname = 'mswin32'; +$cc = 'gcc'; +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'libcrypto.lib', + default => '-lcrypto', +} ), + "_add_to_libs() returned true value"); +like($conf->data->get('libs'), + qr/-lcrypto/, + "'libs' attribute modified as expected"); +# Restore setting for next test +$conf->data->set( libs => $initial_libs ); + +$osname = 'mswin32'; +$cc = 'cc'; +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'libcrypto.lib', + default => '-lcrypto', +} ), + "_add_to_libs() returned true value"); +like($conf->data->get('libs'), + qr/libcrypto.lib/, + "'libs' attribute modified as expected"); +# Restore setting for next test +$conf->data->set( libs => $initial_libs ); + +$osname = 'foobar'; +$cc = 'cc'; +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'libcrypto.lib', + default => '-lcrypto', +} ), + "_add_to_libs() returned true value"); +like($conf->data->get('libs'), + qr/-lcrypto/, + "'libs' attribute modified as expected"); +# Restore setting for next test +$conf->data->set( libs => $initial_libs ); + my ($libs, $ccflags, $linkflags, $verbose); $libs = q{-lalpha}; Index: t/steps/auto_readline-01.t =================================================================== --- t/steps/auto_readline-01.t (revision 27185) +++ t/steps/auto_readline-01.t (working copy) @@ -5,7 +5,7 @@ use strict; use warnings; -use Test::More tests => 46; +use Test::More tests => 47; use Carp; use Cwd; use File::Spec; @@ -16,6 +16,7 @@ use Parrot::Configure; use Parrot::Configure::Options qw( process_options ); use Parrot::Configure::Test qw( test_step_thru_runstep); +use IO::CaptureOutput qw | capture |; my $args = process_options( { @@ -46,25 +47,57 @@ my ($osname, $cc); $osname = 'mswin32'; $cc = 'gcc'; -ok(auto::readline::_handle_mswin32($conf, $osname, $cc), - "_handle_mswin32() returned true value"); +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'readline.lib', + default => '-lreadline', +} ), + "_add_to_libs() returned true value"); like($conf->data->get( 'libs' ), qr/-lreadline/, "'libs' modified as expected"); $osname = 'mswin32'; $cc = 'cc'; -ok(auto::readline::_handle_mswin32($conf, $osname, $cc), - "_handle_mswin32() returned true value"); +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'readline.lib', + default => '-lreadline', +} ), + "_add_to_libs() returned true value"); like($conf->data->get( 'libs' ), qr/readline\.lib/, "'libs' modified as expected"); $osname = 'foobar'; $cc = undef; -ok(auto::readline::_handle_mswin32($conf, $osname, $cc), - "_handle_mswin32() returned true value"); +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'readline.lib', + default => '-lreadline', +} ), + "_add_to_libs() returned true value"); like($conf->data->get( 'libs' ), qr/-lreadline/, "'libs' modified as expected"); +$osname = 'foobar'; +$cc = undef; +eval { + $step->_add_to_libs( [ + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'readline.lib', + default => '-lreadline', + ] ); +}; +like($@, qr/_add_to_libs\(\) takes hashref/, + "Bad argument to _add_to_libs correctly detected"); + my ($flagsbefore, $flagsafter); $osname = 'foobar'; Index: t/steps/auto_gmp-02.t =================================================================== --- t/steps/auto_gmp-02.t (revision 27185) +++ t/steps/auto_gmp-02.t (working copy) @@ -43,27 +43,52 @@ ok( $step->description(), "$step_name has description" ); # Mock values for OS and C-compiler -my ($osname, $cc); +my ($osname, $cc, $initial_value); $osname = 'mswin32'; $cc = 'gcc'; -ok(auto::gmp::_handle_mswin32($conf, $osname, $cc), - "_handle_mswin32() returned true value"); +$initial_value = $conf->data->get( 'libs' ); +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'gmp.lib', + default => '-lgmp', +} ), + "_add_to_libs() returned true value"); like($conf->data->get( 'libs' ), qr/-lgmp/, "'libs' modified as expected"); +# Restore value for next test. +$conf->data->set( 'libs' => $initial_value ); $osname = 'mswin32'; $cc = 'cc'; -ok(auto::gmp::_handle_mswin32($conf, $osname, $cc), - "_handle_mswin32() returned true value"); +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'gmp.lib', + default => '-lgmp', +} ), + "_add_to_libs() returned true value"); like($conf->data->get( 'libs' ), qr/gmp\.lib/, "'libs' modified as expected"); +# Restore value for next test. +$conf->data->set( 'libs' => $initial_value ); $osname = 'foobar'; $cc = undef; -ok(auto::gmp::_handle_mswin32($conf, $osname, $cc), +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'gmp.lib', + default => '-lgmp', +} ), "_handle_mswin32() returned true value"); like($conf->data->get( 'libs' ), qr/-lgmp/, "'libs' modified as expected"); +# Restore value for next test. +$conf->data->set( 'libs' => $initial_value ); my ($flagsbefore, $flagsafter); $osname = 'foobar'; Index: t/steps/auto_gettext-02.t =================================================================== --- t/steps/auto_gettext-02.t (revision 27185) +++ t/steps/auto_gettext-02.t (working copy) @@ -5,7 +5,7 @@ use strict; use warnings; -use Test::More tests => 18; +use Test::More tests => 26; use Carp; use lib qw( lib t/configure/testlib ); use_ok('config::init::defaults'); @@ -41,6 +41,73 @@ isa_ok( $step, $step_name ); ok( $step->description(), "$step_name has description" ); +# Mock values for OS and C-compiler +my ($osname, $cc, $initial_value); +$osname = 'mswin32'; +$cc = 'gcc'; +$initial_value = $conf->data->get( 'libs' ); +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_gcc => '-lintl', + win32_nongcc => 'intl.lib', + default => defined $conf->data->get('glibc') ? '' : '-lintl', +} ), + "_add_to_libs() returned true value"); +like($conf->data->get( 'libs' ), qr/-lintl/, + "'libs' modified as expected"); +# Restore value for next test. +$conf->data->set( 'libs' => $initial_value ); + +$osname = 'mswin32'; +$cc = 'cc'; +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_gcc => '-lintl', + win32_nongcc => 'intl.lib', + default => defined $conf->data->get('glibc') ? '' : '-lintl', +} ), + "_add_to_libs() returned true value"); +like($conf->data->get( 'libs' ), qr/intl.lib/, + "'libs' modified as expected"); +# Restore value for next test. +$conf->data->set( 'libs' => $initial_value ); + +$osname = 'foobar'; +$cc = 'cc'; +$conf->data->set( glibc => 1 ); +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_gcc => '-lintl', + win32_nongcc => 'intl.lib', + default => defined $conf->data->get('glibc') ? '' : '-lintl', +} ), + "_add_to_libs() returned true value"); +unlike($conf->data->get( 'libs' ), qr/-lintl/, + "'libs' modified as expected"); +# Restore value for next test. +$conf->data->set( 'libs' => $initial_value ); + +$osname = 'foobar'; +$cc = 'cc'; +$conf->data->set( glibc => undef ); +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_gcc => '-lintl', + win32_nongcc => 'intl.lib', + default => defined $conf->data->get('glibc') ? '' : '-lintl', +} ), + "_add_to_libs() returned true value"); +like($conf->data->get( 'libs' ), qr/-lintl/, + "'libs' modified as expected"); + my ($test, $verbose); my $has_gettext; Index: t/steps/auto_opengl-02.t =================================================================== --- t/steps/auto_opengl-02.t (revision 27185) +++ t/steps/auto_opengl-02.t (working copy) @@ -5,7 +5,7 @@ use strict; use warnings; -use Test::More tests => 10; +use Test::More tests => 18; use Carp; use lib qw( lib ); use_ok('config::init::defaults'); @@ -38,6 +38,85 @@ isa_ok( $step, $step_name ); ok( $step->description(), "$step_name has description" ); +# Mock OS/C-compiler combinations +my ($osname, $cc, $initial_libs); +$initial_libs = $conf->data->get('libs'); +$osname = 'mswin32'; +$cc = 'gcc'; +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_gcc => '-lglut32 -lglu32 -lopengl32', + win32_nongcc => 'glut.lib glu.lib gl.lib', + darwin => '-framework OpenGL -framework GLUT', + default => '-lglut -lGLU -lGL', +} ), + "_add_to_libs() returned true value"); +like($conf->data->get('libs'), + qr/-lglut32 -lglu32 -lopengl32/, + "'libs' attribute modified as expected"); +# Restore setting for next test +$conf->data->set( libs => $initial_libs ); + +$osname = 'mswin32'; +$cc = 'cc'; +$initial_libs = $conf->data->get('libs'); +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_gcc => '-lglut32 -lglu32 -lopengl32', + win32_nongcc => 'glut.lib glu.lib gl.lib', + darwin => '-framework OpenGL -framework GLUT', + default => '-lglut -lGLU -lGL', +} ), + "_add_to_libs() returned true value"); +like($conf->data->get('libs'), + qr/glut.lib glu.lib gl.lib/, + "'libs' attribute modified as expected"); +# Restore setting for next test +$conf->data->set( libs => $initial_libs ); + +$osname = 'darwin'; +$cc = 'cc'; +$initial_libs = $conf->data->get('libs'); +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_gcc => '-lglut32 -lglu32 -lopengl32', + win32_nongcc => 'glut.lib glu.lib gl.lib', + darwin => '-framework OpenGL -framework GLUT', + default => '-lglut -lGLU -lGL', +} ), + "_add_to_libs() returned true value"); +like($conf->data->get('libs'), + qr/-framework OpenGL -framework GLUT/, + "'libs' attribute modified as expected"); +# Restore setting for next test +$conf->data->set( libs => $initial_libs ); + +$osname = 'foobar'; +$cc = 'cc'; +$initial_libs = $conf->data->get('libs'); +ok($step->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_gcc => '-lglut32 -lglu32 -lopengl32', + win32_nongcc => 'glut.lib glu.lib gl.lib', + darwin => '-framework OpenGL -framework GLUT', + default => '-lglut -lGLU -lGL', +} ), + "_add_to_libs() returned true value"); +like($conf->data->get('libs'), + qr/-lglut -lGLU -lGL/, + "'libs' attribute modified as expected"); +# Restore setting for next test +$conf->data->set( libs => $initial_libs ); + + #my $test = qq{4\n}; #my $has_glut = $step->_evaluate_cc_run($test, undef); #is( $has_glut, 4, "Got expected return value for _evaluate_cc_run()." ); Index: config/auto/opengl.pm =================================================================== --- config/auto/opengl.pm (revision 27185) +++ config/auto/opengl.pm (working copy) @@ -53,7 +53,15 @@ my $osname = $conf->data->get_p5('OSNAME'); - _handle_mswin32($conf, $osname, $cc); + $self->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_gcc => '-lglut32 -lglu32 -lopengl32', + win32_nongcc => 'glut.lib glu.lib gl.lib', + darwin => '-framework OpenGL -framework GLUT', + default => '-lglut -lGLU -lGL', + } ); # On OS X check the presence of the OpenGL headers in the standard # Fink/macports locations. @@ -76,26 +84,6 @@ return 1; } -sub _handle_mswin32 { - my ($conf, $osname, $cc) = @_; - # Mindlessly morphed from readline ... may need to be fixed - if ( $osname =~ /mswin32/i ) { - if ( $cc =~ /^gcc/i ) { - $conf->data->add( ' ', libs => '-lglut32 -lglu32 -lopengl32' ); - } - else { - $conf->data->add( ' ', libs => 'glut.lib glu.lib gl.lib' ); - } - } - elsif ( $osname =~ /darwin/i ) { - $conf->data->add( ' ', libs => '-framework OpenGL -framework GLUT' ); - } - else { - $conf->data->add( ' ', libs => '-lglut -lGLU -lGL' ); - } - return 1; -} - sub _evaluate_cc_run { my ($self, $test, $verbose) = @_; my ($glut_api_version, $glut_brand) = split ' ', $test; Index: config/auto/gettext.pm =================================================================== --- config/auto/gettext.pm (revision 27185) +++ config/auto/gettext.pm (working copy) @@ -57,7 +57,14 @@ my $osname = $conf->data->get_p5('OSNAME'); - _handle_mswin32($conf, $osname, $cc); + $self->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_gcc => '-lintl', + win32_nongcc => 'intl.lib', + default => defined $conf->data->get('glibc') ? '' : '-lintl', + } ); # On OS X check the presence of the gettext header in the standard # Fink location. @@ -82,24 +89,6 @@ return 1; } -sub _handle_mswin32 { - my ($conf, $osname, $cc) = @_; - if ( $osname =~ /mswin32/i ) { - if ( $cc =~ /^gcc/i ) { - $conf->data->add( ' ', libs => '-lintl' ); - } - else { - $conf->data->add( ' ', libs => 'intl.lib' ); - } - } - else { - # don't need to link with libintl if we have GNU libc - my $linklibs = defined $conf->data->get('glibc') ? '' : '-lintl'; - $conf->data->add( ' ', libs => $linklibs ); - } - return 1; -} - sub _evaluate_cc_run { my $self = shift; my ($test, $verbose) = @_; Index: config/auto/gmp.pm =================================================================== --- config/auto/gmp.pm (revision 27185) +++ config/auto/gmp.pm (working copy) @@ -63,7 +63,13 @@ my $osname = $conf->data->get_p5('OSNAME'); - _handle_mswin32($conf, $osname, $cc); + $self->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'gmp.lib', + default => '-lgmp', + } ); # On OS X check the presence of the gmp header in the standard # Fink location. @@ -85,22 +91,6 @@ return 1; } -sub _handle_mswin32 { - my ($conf, $osname, $cc) = @_; - if ( $osname =~ /mswin32/i ) { - if ( $cc =~ /^gcc/i ) { - $conf->data->add( ' ', libs => '-lgmp' ); - } - else { - $conf->data->add( ' ', libs => 'gmp.lib' ); - } - } - else { - $conf->data->add( ' ', libs => '-lgmp' ); - } - return 1; -} - sub _evaluate_cc_run { my ($self, $conf, $test, $has_gmp, $verbose) = @_; if ( $test eq $self->{cc_run_expected} ) { Index: config/auto/crypto.pm =================================================================== --- config/auto/crypto.pm (revision 27185) +++ config/auto/crypto.pm (working copy) @@ -52,7 +52,13 @@ my $osname = $conf->data->get_p5('OSNAME'); - _handle_mswin32($conf, $osname, $cc); + $self->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'libcrypto.lib', + default => '-lcrypto', + } ); $conf->cc_gen('config/auto/crypto/crypto.in'); eval { $conf->cc_build(); }; @@ -70,22 +76,6 @@ return 1; } -sub _handle_mswin32 { - my ($conf, $osname, $cc) = @_; - if ( $osname =~ /mswin32/i ) { - if ( $cc =~ /^gcc/i ) { - $conf->data->add( ' ', libs => '-lcrypto' ); - } - else { - $conf->data->add( ' ', libs => 'libcrypto.lib' ); - } - } - else { - $conf->data->add( ' ', libs => '-lcrypto' ); - } - return 1; -} - sub _evaluate_cc_run { my $self = shift; my ($conf, $test, $has_crypto, $verbose) = @_; Index: config/auto/readline.pm =================================================================== --- config/auto/readline.pm (revision 27185) +++ config/auto/readline.pm (working copy) @@ -45,7 +45,13 @@ my $osname = $conf->data->get_p5('OSNAME'); - _handle_mswin32($conf, $osname, $cc); + $self->_add_to_libs( { + conf => $conf, + osname => $osname, + cc => $cc, + win32_nongcc => 'readline.lib', + default => '-lreadline', + } ); # On OS X check the presence of the readline header in the standard # Fink/macports locations. @@ -79,22 +85,6 @@ return 1; } -sub _handle_mswin32 { - my ($conf, $osname, $cc) = @_; - if ( $osname =~ /mswin32/i ) { - if ( $cc =~ /^gcc/i ) { - $conf->data->add( ' ', libs => '-lreadline' ); - } - else { - $conf->data->add( ' ', libs => 'readline.lib' ); - } - } - else { - $conf->data->add( ' ', libs => '-lreadline' ); - } - return 1; -} - sub _handle_ncurses_need { my ($conf, $osname, $cc) = @_; if ( $osname =~ /mswin32/i ) {