diff --git a/Configure.pl b/Configure.pl index d5d026d..077805e 100644 --- a/Configure.pl +++ b/Configure.pl @@ -1,62 +1,188 @@ -# $Id$ -# Copyright (C) 2009, The Perl Foundation. +#! perl + +=head1 NAME + +Configure.pl - a configure script for a high level language running on Parrot + +=head1 SYNOPSIS + + perl Configure.pl --help + + perl Configure.pl + + perl Configure.pl --parrot_config= + + perl Configure.pl --gen-parrot + +=cut use strict; use warnings; use 5.008; +# core Perl 5 modules +use File::Spec (); + +# Modules from CPAN +use File::Which (); + +my %valid_options = ( + 'help' => 'Display configuration help', + 'parrot-config' => 'Use configuration given by parrot_config binary', + 'gen-parrot' => 'Automatically retrieve and build Parrot', +); + + +# Get any options from the command line +my %options = get_command_options(); + + +# Print help if it's requested +if ($options{'help'}) { + print_help(); + exit(0); +} + + +# Update/generate parrot build if needed +if ($options{'gen-parrot'}) { + system("$^X build/gen_parrot.pl"); +} + + # Get a list of parrot-configs to invoke. my @parrot_config_exe = ( - 'parrot/parrot_config', + 'parrot/parrot_config', '../../parrot_config', - 'parrot_config', + 'parrot_config' ); +if ($options{'parrot-config'} && $options{'parrot-config'} ne '1') { + @parrot_config_exe = ($options{'parrot-config'}); +} # Get configuration information from parrot_config my %config = read_parrot_config(@parrot_config_exe); unless (%config) { - die "Unable to locate parrot_config."; + die <<"END"; +Unable to locate parrot_config. +To automatically checkout (svn) and build a copy of parrot, +try re-running Configure.pl with the '--gen-parrot' option. +Or, use the '--parrot-config' option to explicitly specify +the location of parrot_config. +END } # Create the Makefile using the information we just got -create_makefiles(%config); +create_files( + \%config, + { 'build/templates/Makefile.in' => 'Makefile', + } +); + +# Done. +done($config{'make'}); + + +# Process command line arguments into a hash. +sub get_command_options { + my %options = (); + for my $arg (@ARGV) { + if ($arg =~ /^--(\w[-\w]*)(?:=(.*))?/ && $valid_options{$1}) { + my ($key, $value) = ($1, $2); + $value = 1 unless defined $value; + $options{$key} = $value; + next; + } + die qq/Invalid option "$arg". See "perl Configure.pl --help" for valid options.\n/; + } + %options; +} + sub read_parrot_config { my @parrot_config_exe = @_; - my %config = (); + my %config; for my $exe (@parrot_config_exe) { no warnings; - if (open my $PARROT_CONFIG, '-|', "$exe --dump") { + if (open my $parrot_config_fh, '-|', "$exe --dump") { print "Reading configuration information from $exe\n"; - while (<$PARROT_CONFIG>) { - $config{$1} = $2 if (/(\w+) => '(.*)'/); + while (<$parrot_config_fh>) { + if (/(\w+) => '(.*)'/) { $config{$1} = $2 } + } + close $parrot_config_fh; + + if (%config) { + my $parrot_config_exe = File::Which::which($exe) if $exe eq 'parrot_config'; + $parrot_config_exe ||= File::Spec->rel2abs($exe); + $parrot_config_exe ||= File::Spec->rel2abs("$exe$config{EXE}"); + $parrot_config_exe ||= $exe; + $config{parrot_config_exe} = $parrot_config_exe; + last; } - close $PARROT_CONFIG; - last if %config; } } - %config; + + return %config; } -# Generate Makefiles from a configuration -sub create_makefiles { - my %config = @_; - my %makefiles = ( - 'config/makefiles/root.in' => 'Makefile', -# 'config/makefiles/pmc.in' => 'src/pmc/Makefile', -# 'config/makefiles/ops.in' => 'src/ops/Makefile', - ); - my $build_tool = $config{libdir} . $config{versiondir} - . '/tools/dev/gen_makefile.pl'; - - foreach my $template (keys %makefiles) { - my $makefile = $makefiles{$template}; - print "Creating $makefile\n"; - system($config{perl}, $build_tool, $template, $makefile); +# Generate a Makefile from a configuration +sub create_files { + my ($config, $setup) = @_; + + while (my ($template_fn, $target_fn) = each %{$setup}) { + my $content; + { + open my $template_fh, '<', $template_fn or + die "Unable to read $template_fn."; + $content = join('', <$template_fh>); + close $template_fn; + } + + $config->{'win32_libparrot_copy'} = $^O eq 'MSWin32' ? 'copy $(BUILD_DIR)\libparrot.dll .' : ''; + $content =~ s/@(\w+)@/$config->{$1}/g; + if ($^O eq 'MSWin32') { + $content =~ s{/}{\\}g; + } + + print "Creating $target_fn from $template_fn.\n"; + { + open(my $target_fh, '>', $target_fn) + or die "Unable to write $target_fn\n"; + print $target_fh $content; + close($target_fh); + } } } + +sub done { + my ($make) = @_; + print <<"END"; + +You can now use '$make' to build unlambda. +After that, you can use '$make test' to run some local tests. +See 'docs/testing.pod' for how to run the PHP 5.3 testsuite. + +END + exit 0; +} + + +# Print some help text. +sub print_help { + print <<'END'; +Configure.pl - Rakudo Configure + +General Options: + --help Show this text + --gen-parrot Download and build a copy of Parrot to use + --parrot-config=(config) + Use configuration information from config + +END +} + # Local Variables: # mode: cperl # cperl-indent-level: 4 diff --git a/build/PARROT_REVISION b/build/PARROT_REVISION new file mode 100644 index 0000000..aa0b4c7 --- /dev/null +++ b/build/PARROT_REVISION @@ -0,0 +1 @@ +37614 diff --git a/build/gen_parrot.pl b/build/gen_parrot.pl new file mode 100644 index 0000000..f20e2e6 --- /dev/null +++ b/build/gen_parrot.pl @@ -0,0 +1,80 @@ +#! perl +# Copyright (C) 2009 The Perl Foundation + +=head1 TITLE + +gen_parrot.pl - script to obtain and build Parrot for Rakudo + +=head2 SYNOPSIS + + perl gen_parrot.pl + +=head2 DESCRIPTION + +Maintains an appropriate copy of Parrot in the parrot/ subdirectory. +The revision of Parrot to be used in the build is given by the +build/PARROT_REVISION file. + +=cut + +use strict; +use warnings; +use 5.008; + +# Work out slash character to use. +my $slash = $^O eq 'MSWin32' ? '\\' : '/'; + +## determine what revision of Parrot we require +open my $REQ, "build/PARROT_REVISION" + || die "cannot open build/PARROT_REVISION\n"; +my $required = <$REQ>; chomp $required; +close $REQ; + +{ + no warnings; + if (open my $REV, '-|', "parrot${slash}parrot_config revision") { + my $revision = <$REV>; + close $REV; + chomp $revision; + if ($revision >= $required) { + print "Parrot r$revision already available (r$required required)\n"; + exit(0); + } + } +} + +print "Checking out Parrot r$required via svn...\n"; +system("svn checkout -r $required https://svn.parrot.org/parrot/trunk parrot"); + +chdir('parrot'); + + +## If we have a Makefile from a previous build, do a 'make realclean' +if (-f 'Makefile') { + my %config = read_parrot_config(); + my $make = $config{'make'}; + if ($make) { + print "Performing '$make realclean'\n"; + system("$make realclean"); + } +} + +## Configure Parrot +system("$^X Configure.pl"); + +my %config = read_parrot_config(); +my $make = $config{'make'}; + +system($make); + +sub read_parrot_config { + my %config = (); + if (open my $CFG, "config_lib.pasm") { + while (<$CFG>) { + if (/P0\["(.*?)"], "(.*?)"/) { $config{$1} = $2 } + } + close $CFG; + } + %config; +} + diff --git a/config/makefiles/root.in b/build/templates/Makefile.in similarity index 98% rename from config/makefiles/root.in rename to build/templates/Makefile.in index ce24eb5..084bab0 100644 --- a/config/makefiles/root.in +++ b/build/templates/Makefile.in @@ -48,7 +48,7 @@ installable_lazy@exe@: lazy.pbc $(PBC_TO_EXE) lazy.pbc --install # regenerate the Makefile -Makefile: config/makefiles/root.in +Makefile: build/templates/Makefile.in $(PERL) Configure.pl # This is a listing of all targets, that are meant to be called by users