From f4632b9b729b4f2df4b2af111e2583feac178dd5 Mon Sep 17 00:00:00 2001 From: Moritz Lenz Date: Mon, 28 May 2012 14:09:59 +0200 Subject: [build] add a basic template mechanism this grabs the {parrot,rakudo,nqp} revisions and fudges them into Configure.pl, so at least it is one less location to update --- Makefile | 1 + build/skel-template.pl | 53 +++++++++++++ skel/Configure.pl | 182 ------------------------------------------ template-skel/Configure.pl | 194 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 248 insertions(+), 182 deletions(-) create mode 100644 build/skel-template.pl delete mode 100644 skel/Configure.pl create mode 100644 template-skel/Configure.pl diff --git a/Makefile b/Makefile index f51e854..aead8c9 100644 --- a/Makefile +++ b/Makefile @@ -66,6 +66,7 @@ always: $(DISTDIR): always mkdir -p $(DISTDIR) cp -av skel/. $(DISTDIR) + perl build/skel-template.pl $(DISTDIR) $(PARROT_DIR): $(PARROT_TGZ) tar -C $(DISTDIR) -xvzf $(PARROT_TGZ) diff --git a/build/skel-template.pl b/build/skel-template.pl new file mode 100644 index 0000000..8940d33 --- /dev/null +++ b/build/skel-template.pl @@ -0,0 +1,53 @@ +use strict; +use warnings; + +my $destination = shift(@ARGV) || die "Usage: $0 "; +unless (-d $destination) { + die "Destination '$destination' should be a directory, but is not"; +} + +my %look_for = (PARROT_VER => 1, RAKUDO_VER => 1, NQP_VER => 1); +my %vars; + +open my $fh, '<', 'Makefile' + or die "Cannot open Makefile for reading: $!"; + +while (<$fh>) { + chomp; + if (/^(\w+)\s*=\s*(\S*)/ && $look_for{$1}) { + delete $look_for{$1}; + $vars{$1} = $2; + last unless %look_for; + } +} +close $fh; +if (%look_for) { + die "Couldn't find a definition for the following variable(s) in Makfile\n" + . join(', ', keys %look_for) . "\n"; +} + +my $subst_re = join '|', map quotemeta, keys %vars; +$subst_re = qr{\<($subst_re)\>}; + +# XXX recursive traversal + templating NYI, one level is enough for a start + +for my $file (glob 'template-skel/*') { + my $dest = $file; + $dest =~ s{^template-skel/}{$destination/}; + process_file($file, $dest); +} + +sub process_file { + my ($source, $dest) = @_; + print "Processing '$source' into '$dest'\n"; + open my $in, '<', $source + or die "Cannot open '$source' for reading: $!"; + open my $out, '>', $dest + or die "Cannot open '$dest' for writing: $!"; + while (<$in>) { + s/$subst_re/$vars{$1}/g; + print { $out } $_ or die "Cannot write to '$dest': $!"; + } + close $in; + close $out or die "Cannot close '$dest': $!"; +} diff --git a/skel/Configure.pl b/skel/Configure.pl deleted file mode 100644 index 90cac74..0000000 --- a/skel/Configure.pl +++ /dev/null @@ -1,182 +0,0 @@ -#! perl -# Copyright (C) 2009 The Perl Foundation - -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!', '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'}) { - print_help(); - exit(0); - } - - - my $prefix = $options{'prefix'} || cwd().'/install'; - my $with_parrot = $options{'with-parrot'}; - $options{'gen-parrot'} ||= 'parrot-4.4.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); - } - - # --with-parrot and --gen-parrot imply --gen-nqp - if (defined $with_parrot || defined $gen_parrot) { - $options{'gen-nqp'} ||= ''; - } - - $options{'gen-nqp'} ||= 'nqp-2012.05' if defined $options{'gen-nqp'}; - my $with_nqp = $options{'with-nqp'}; - my $gen_nqp = $options{'gen-nqp'}; - - # determine the version of NQP we want - my ($nqp_want) = split(' ', slurp('rakudo-2012.05/tools/build/NQP_REVISION')); - - if (defined $gen_nqp) { - $with_nqp = gen_nqp($nqp_want, %options); - } - - my @errors; - - 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) - } - - %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)."; - } - - 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; - } - - 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."; - } - - sorry(@errors) if @errors; - - 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); - - { - no warnings; - print "Cleaning up ...\n"; - if (open my $CLEAN, '-|', "$make clean") { - my @slurp = <$CLEAN>; - close($CLEAN); - } - } - - if ($options{'make-install'}) { - system_or_die($make); - system_or_die($make, 'install'); - print "\n$lang has been built and installed.\n"; - } - 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"; - } - - exit 0; -} - - -# Print some help text. -sub print_help { - print <<"END"; -Configure.pl - $lang Configure - -General Options: - --help Show this text - --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; -} - -# Local Variables: -# mode: cperl -# cperl-indent-level: 4 -# fill-column: 100 -# End: -# vim: expandtab shiftwidth=4: diff --git a/template-skel/Configure.pl b/template-skel/Configure.pl new file mode 100644 index 0000000..02aaf31 --- /dev/null +++ b/template-skel/Configure.pl @@ -0,0 +1,194 @@ +#! perl +# Copyright (C) 2009 The Perl Foundation + +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 $parrot_ver = ''; +my $nqp_ver = ''; +my $rakudo_ver = ''; + +for ($parrot_ver, $nqp_ver, $rakudo_ver) { + if (/^<\w+_VER>/) { + die "You are running the original version of Configure.pl,\n" + . "but you should only run a version which has been processed by\n" + . "build/skel-template.pl\n"; + } +} + +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!', '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'}) { + print_help(); + exit(0); + } + + + my $prefix = $options{'prefix'} || cwd().'/install'; + my $with_parrot = $options{'with-parrot'}; + $options{'gen-parrot'} ||= "parrot-$parrot_ver" 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); + } + + # --with-parrot and --gen-parrot imply --gen-nqp + if (defined $with_parrot || defined $gen_parrot) { + $options{'gen-nqp'} ||= ''; + } + + $options{'gen-nqp'} ||= "nqp-$nqp_ver" if defined $options{'gen-nqp'}; + my $with_nqp = $options{'with-nqp'}; + my $gen_nqp = $options{'gen-nqp'}; + + # determine the version of NQP we want + my ($nqp_want) = split(' ', slurp("rakudo-$rakudo_ver/tools/build/NQP_REVISION")); + + if (defined $gen_nqp) { + $with_nqp = gen_nqp($nqp_want, %options); + } + + my @errors; + + 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) + } + + %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)."; + } + + 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; + } + + 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."; + } + + sorry(@errors) if @errors; + + 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); + + { + no warnings; + print "Cleaning up ...\n"; + if (open my $CLEAN, '-|', "$make clean") { + my @slurp = <$CLEAN>; + close($CLEAN); + } + } + + if ($options{'make-install'}) { + system_or_die($make); + system_or_die($make, 'install'); + print "\n$lang has been built and installed.\n"; + } + 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"; + } + + exit 0; +} + + +# Print some help text. +sub print_help { + print <<"END"; +Configure.pl - $lang Configure + +General Options: + --help Show this text + --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; +} + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: -- cgit v1.1 From 2663a4881dd24a7d42007adbf870302e73cbf779 Mon Sep 17 00:00:00 2001 From: Moritz Lenz Date: Mon, 28 May 2012 14:12:03 +0200 Subject: [build] fix add a small comment --- build/skel-template.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build/skel-template.pl b/build/skel-template.pl index 8940d33..0e355fe 100644 --- a/build/skel-template.pl +++ b/build/skel-template.pl @@ -1,3 +1,8 @@ +# grabs some variables (containing versions) from Makefile, +# and then copies files from template-skel over to the +# dist folder, replacing occurrences of those variables +# in the process. + use strict; use warnings; -- cgit v1.1