From 7c94ff394fcd7e5139106cf10c7a7c69265a8b71 Mon Sep 17 00:00:00 2001 From: pmichaud Date: Fri, 27 Jan 2012 11:04:25 -0600 Subject: Initial re-write of Configure.pl (based on Rakudo's Configure.pl, with new options for --gen-nqp and --gen-parrot.) --- skel/Configure.pl | 288 ++++++++++++++++++++++-------------------------------- 1 file changed, 119 insertions(+), 169 deletions(-) diff --git a/skel/Configure.pl b/skel/Configure.pl index 3a2885a..3f08535 100644 --- a/skel/Configure.pl +++ b/skel/Configure.pl @@ -4,13 +4,35 @@ use 5.008; use strict; use warnings; +use Text::ParseWords; use Getopt::Long; use Cwd; +use lib "tools/lib"; +use NQP::Configure qw(sorry slurp cmp_rev gen_nqp read_config + fill_template_text fill_template_file + system_or_die verify_install); + +my $lang = 'Rakudo'; +my $lclang = lc $lang; +my $uclang = uc $lang; MAIN: { + if (-r "config.default") { + unshift @ARGV, shellwords(slurp('config.default')); + } + + my %config; + my $config_status = "${lclang}_config_status"; + $config{$config_status} = join(' ', map { "\"$_\""} @ARGV); + + my $exe = $NQP::Configure::exe; + my %options; - GetOptions(\%options, 'help!', 'parrot-config=s', 'makefile-timing!', - 'gen-parrot!', 'prefix=s', 'gen-parrot-option=s@'); + GetOptions(\%options, 'help!', 'prefix=s', + 'with-nqp=s', 'gen-nqp:s', + 'with-parrot=s', 'gen-parrot:s', 'parrot-option=s@', + 'make-install!', 'makefile-timing!', + ); # Print help if it's requested if ($options{'help'}) { @@ -18,207 +40,135 @@ MAIN: { exit(0); } - # Determine the revision of Parrot we require - open my $REQ, '<', "build/PARROT_REVISION" - or die "cannot open build/PARROT_REVISION: $!\n"; - my ($reqsvn, $reqpar) = split(' ', <$REQ>); - $reqsvn += 0; - close $REQ; - - # Update/generate parrot build if needed - if ($options{'gen-parrot'}) { - my @opts = @{ $options{'gen-parrot-option'} || [] }; - my $prefix = $options{'prefix'} || cwd()."/install"; - # parrot's Configure.pl mishandles win32 backslashes in --prefix - $prefix =~ s{\\}{/}g; - my @command = ($^X, "build/gen_parrot.pl", "--prefix=$prefix", - ($^O !~ /win32/i ? "--optimize" : ()), @opts); - - print "Generating Parrot ...\n"; - print "@command\n\n"; - system @command; - } - # Get a list of parrot-configs to invoke. - my @parrot_config_exe = qw( - install/bin/parrot_config - parrot_config - ); - if (exists $options{'prefix'}) { - unshift @parrot_config_exe, - $options{'prefix'} . '/bin/parrot_config'; + my $prefix = $options{'prefix'} || cwd().'/install'; + my $with_parrot = $options{'with-parrot'}; + $options{'gen-parrot'} ||= 'parrot-3.11.0' if defined $options{'gen-parrot'}; + my $gen_parrot = $options{'gen-parrot'}; + + # Save options in config.status + unlink('config.status'); + if (open(my $CONFIG_STATUS, '>', 'config.status')) { + print $CONFIG_STATUS + "$^X Configure.pl $config{$config_status} \$*\n"; + close($CONFIG_STATUS); } - if ($options{'parrot-config'} && $options{'parrot-config'} ne '1') { - @parrot_config_exe = ($options{'parrot-config'}); + # --with-parrot and --gen-parrot imply --gen-nqp + if (defined $with_parrot || defined $gen_parrot) { + $options{'gen-nqp'} ||= ''; } - # Get configuration information from parrot_config - my %config = read_parrot_config(@parrot_config_exe); + $options{'gen-nqp'} ||= 'nqp-2012.01' if defined $options{'gen-nqp'}; + my $with_nqp = $options{'with-nqp'}; + my $gen_nqp = $options{'gen-nqp'}; - my $parrot_errors = ''; - if (!%config) { - $parrot_errors .= "Unable to locate parrot_config\n"; - } - elsif ($reqsvn > $config{'revision'} && - ($reqpar eq '' || version_int($reqpar) > version_int($config{'VERSION'}))) { - $parrot_errors .= "Parrot revision r$reqsvn required (currently r$config{'revision'})\n"; + # determine the version of NQP we want + my ($nqp_want) = split(' ', slurp('tools/build/NQP_REVISION')); + + if (defined $gen_nqp) { + $with_nqp = gen_nqp($nqp_want, %options); } - if ($parrot_errors) { - die <<"END"; -===SORRY!=== -$parrot_errors -To automatically build the version of Parrot that came with this -distribution ($reqpar), try re-running Configure.pl with the -'--gen-parrot' option. Or, use the '--parrot-config' option to -explicitly specify the location of parrot_config to be used to -build Rakudo Star. + my @errors; -END + my %nqp_config; + if ($with_nqp) { + %nqp_config = read_config($with_nqp) + or push @errors, "Unable to read configuration from $with_nqp."; + } + else { + %nqp_config = read_config("$prefix/bin/nqp$exe", "nqp$exe") + or push @errors, "Unable to find an NQP executable."; + $with_nqp = fill_template_text('@bindir@/nqp@exe@', %nqp_config) } - # Verify the Parrot installation is sufficient for building Rakudo - verify_parrot(%config); - - # Create the Makefile using the information we just got - create_makefile($options{'makefile-timing'}, %config); - my $make = $config{'make'}; + %config = (%config, %nqp_config); + my $nqp_have = $config{'nqp::version'} || ''; + if ($nqp_have && cmp_rev($nqp_have, $nqp_want) < 0) { + push @errors, "NQP revision $nqp_want required (currently $nqp_have)."; + } - { - no warnings; - print "Cleaning up ...\n"; - if (open my $CLEAN, '-|', "$make clean") { - my @slurp = <$CLEAN>; - close $CLEAN; - } + if (!@errors) { + push @errors, verify_install([ @NQP::Configure::required_parrot_files, + @NQP::Configure::required_nqp_files ], + %config); + push @errors, + "(Perhaps you need to 'make install', 'make install-dev',", + "or install the 'devel' package for NQP or Parrot?)" + if @errors; } - print <<"END"; + if (@errors && !defined $gen_nqp) { + push @errors, + "\nTo automatically clone (git) and build a copy of NQP $nqp_want,", + "try re-running Configure.pl with the '--gen-nqp' or '--gen-parrot'", + "options. Or, use '--with-nqp=' or '--with-parrot=' to explicitly", + "specify the NQP or Parrot executable to use to build $lang."; + } -You can now use '$make' to build Rakudo Perl. -After that, you can use '$make rakudo-test' to run some local tests, -or '$make install' to create a 'perl6' executable in the local directory -and in $config{'bindir'}/perl6 . + sorry(@errors) if @errors; -END - exit 0; + print "Using $with_nqp (version $config{'nqp::version'}).\n"; -} + $config{'makefile-timing'} = $options{'makefile-timing'}; + $config{'stagestats'} = '--stagestats' if $options{'makefile-timing'}; + $config{'shell'} = $^O eq 'MSWin32' ? 'cmd' : 'sh'; + if ($^O eq 'MSWin32' or $^O eq 'cygwin') { + $config{'dll'} = '$(PARROT_BIN_DIR)/$(PARROT_LIB_SHARED)'; + $config{'dllcopy'} = '$(PARROT_LIB_SHARED)'; + $config{'make_dllcopy'} = + '$(PARROT_DLL_COPY): $(PARROT_DLL)'."\n\t".'$(CP) $(PARROT_DLL) .'; + } + my $make = fill_template_text('@make@', %config); + fill_template_file('tools/build/Makefile.in', 'Makefile', %config); -sub read_parrot_config { - my @parrot_config_exe = @_; - my %config = (); - for my $exe (@parrot_config_exe) { + { no warnings; - if (open my $PARROT_CONFIG, '-|', "$exe --dump") { - print "\nReading configuration information from $exe ...\n"; - while (<$PARROT_CONFIG>) { - if (/(\w+) => '(.*)'/) { $config{$1} = $2 } - } - close $PARROT_CONFIG or die $!; - last if %config; + print "Cleaning up ...\n"; + if (open my $CLEAN, '-|', "$make clean") { + my @slurp = <$CLEAN>; + close($CLEAN); } } - return %config; -} - - -sub verify_parrot { - print "Verifying Parrot installation...\n"; - my %config = @_; - my $EXE = $config{'exe'}; - my $PARROT_BIN_DIR = $config{'bindir'}; - my $PARROT_VERSION = $config{'versiondir'}; - my $PARROT_LIB_DIR = $config{'libdir'}.$PARROT_VERSION; - my $PARROT_SRC_DIR = $config{'srcdir'}.$PARROT_VERSION; - my $PARROT_INCLUDE_DIR = $config{'includedir'}.$PARROT_VERSION; - my $PARROT_TOOLS_DIR = "$PARROT_LIB_DIR/tools"; - my @required_files = ( - "$PARROT_LIB_DIR/library/PGE/Perl6Grammar.pbc", - "$PARROT_LIB_DIR/library/PCT/HLLCompiler.pbc", - "$PARROT_BIN_DIR/ops2c".$EXE, - "$PARROT_TOOLS_DIR/build/pmc2c.pl", - "$PARROT_SRC_DIR", - "$PARROT_SRC_DIR/pmc", - "$PARROT_INCLUDE_DIR", - "$PARROT_INCLUDE_DIR/pmc", - ); - my @missing = map { " $_" } grep { ! -e } @required_files; - if (@missing) { - my $missing = join("\n", @missing); - die <<"END"; - -===SORRY!=== -I'm missing some needed files from the Parrot installation: -$missing -(Perhaps you need to use Parrot's "make install-dev" or -install the "parrot-devel" package for your system?) -END + if ($options{'make-install'}) { + system_or_die($make); + system_or_die($make, 'install'); + print "\n$lang has been built and installed.\n"; } -} - -# Generate a Makefile from a configuration -sub create_makefile { - my ($makefile_timing, %config) = @_; - - my $maketext = slurp( 'build/Makefile.in' ); - - $config{'stagestats'} = $makefile_timing ? '--stagestats' : ''; - $config{'win32_libparrot_copy'} = $^O eq 'MSWin32' ? 'copy $(PARROT_BIN_DIR)\libparrot.dll .' : ''; - $maketext =~ s/@(\w+)@/$config{$1}/g; - if ($^O eq 'MSWin32') { - $maketext =~ s{/}{\\}g; - $maketext =~ s{\\\*}{\\\\*}g; - $maketext =~ s{http:\S+}{ do {my $t = $&; $t =~ s'\\'/'g; $t} }eg; + else { + print "\nYou can now use '$make' to build $lang.\n"; + print "After that, '$make test' will run some tests and\n"; + print "'$make install' will install $lang.\n"; } - if ($makefile_timing) { - $maketext =~ s{(?', $outfile) || - die "Unable to write $outfile\n"; - print {$MAKEOUT} $maketext; - close $MAKEOUT or die $!; - - return; -} - -sub slurp { - my $filename = shift; - - open my $fh, '<', $filename or die "Unable to read $filename\n"; - local $/ = undef; - my $maketext = <$fh>; - close $fh or die $!; - - return $maketext; -} - -sub version_int { - sprintf('%d%03d%03d', split(/\./, $_[0])) + exit 0; } # Print some help text. sub print_help { - print <<'END'; -Configure.pl - Rakudo Configure + print <<"END"; +Configure.pl - $lang Configure General Options: --help Show this text - --gen-parrot Download and build a copy of Parrot to use - --gen-parrot-option='--option=value' - Set parrot config option when using --gen-parrot - --parrot-config=/path/to/parrot_config - Use config information from parrot_config executable -Experimental developer's options: - --makefile-timing Insert 'time' command all over in the Makefile + --prefix=dir Install files in dir + --with-nqp=path/to/bin/nqp + NQP executable to use to build $lang + --gen-nqp[=branch] + Download and build a copy of NQP + --with-parrot=path/to/bin/parrot + Parrot executable to use to build NQP + --gen-parrot[=branch] + Download and build a copy of Parrot + --parrot-option='--option' + Options to pass to Parrot's Configure.pl + --makefile-timing Enable timing of individual makefile commands + +Configure.pl also reads options from 'config.default' in the current directory. END return; -- cgit v1.1