Skip to content

Commit

Permalink
New Configure/build system, part 1.
Browse files Browse the repository at this point in the history
  • Loading branch information
pmichaud committed Jun 8, 2011
1 parent 151d38f commit 7ec8cf2
Show file tree
Hide file tree
Showing 5 changed files with 387 additions and 197 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
src/gen/*
Perl6/*
nqp/
install/
Makefile
.*.swp
*.patch
Expand All @@ -25,7 +26,6 @@ perl6.rc
t/localtest.data
t/spec
parrot
parrot_install
perl6
perl6.c
perl6.o
Expand Down
232 changes: 36 additions & 196 deletions Configure.pl
Original file line number Diff line number Diff line change
Expand Up @@ -6,231 +6,71 @@
use warnings;
use Getopt::Long;
use Cwd;
use lib "build/lib";
use Parrot::CompareRevisions qw(compare_revs parse_revision_file read_config version_from_git_describe);
use lib "tools/lib";
use NQP::Configure qw(slurp gen_nqp read_config fill_template_file);


MAIN: {
my %config;
$config{'rakudo_config_status'} = join(' ', map { "\"$_\""} @ARGV);

my %options;
GetOptions(\%options, 'help!', 'parrot-config=s', 'makefile-timing!',
'gen-parrot!', 'gen-parrot-prefix=s', 'gen-parrot-option=s@',
'gen-nqp!');
GetOptions(\%options, 'help!', 'prefix=s',
'with-nqp=s', 'gen-nqp:s',
'with-parrot=s', 'gen-parrot:s',
'make-install!', 'makefile-timing!',
);

# Print help if it's requested
if ($options{'help'}) {
print_help();
exit(0);
}

# Update/generate parrot build if needed
if ($options{'gen-parrot'}) {
my @opts = @{ $options{'gen-parrot-option'} || [] };
my $prefix = $options{'gen-parrot-prefix'} || cwd()."/parrot_install";
# parrot's Configure.pl mishandles win32 backslashes in --prefix
$prefix =~ s{\\}{/}g;
my @command = ($^X, "build/gen_parrot.pl", "--prefix=$prefix",
'--gc=gms', ($^O !~ /win32/i ? "--optimize" : ()), @opts);

print "Generating Parrot ...\n";
print "@command\n\n";
system(@command) == 0
or die "Error while executing @command; aborting\n";
}

# Update/generate NQP build if needed.
if ($options{'gen-nqp'}) {
my @command = ($^X, "build/gen_nqp.pl");
print "Generating NQP ...\n";
print "@command\n\n";
system(@command) == 0
or die "Error while executing @command; aborting\n";
}

# Get a list of parrot-configs to invoke.
my @parrot_config_exe = qw(
parrot_install/bin/parrot_config
../../parrot_config
parrot_config
);
if (exists $options{'gen-parrot-prefix'}) {
@parrot_config_exe =
$options{'gen-parrot-prefix'} . '/bin/parrot_config';
}

if ($options{'parrot-config'} && $options{'parrot-config'} ne '1') {
@parrot_config_exe = ($options{'parrot-config'});
}

# Get configuration information from parrot_config
my ($parrot_config, %config) = read_config(@parrot_config_exe);

# Determine the revision of Parrot we require
my $git_describe = parse_revision_file;
my $parrot_version = version_from_git_describe($git_describe);

my $parrot_errors = '';
if (!%config) {
$parrot_errors .= "Unable to locate parrot_config\n";
}
else {
if ($config{git_describe}) {
# a parrot built from git
if (compare_revs($git_describe, $config{'git_describe'}) > 0) {
$parrot_errors .= "Parrot revision $git_describe required (currently $config{'git_describe'})\n";
}
}
else {
# not built from a git repo - let's assume it's a release
if (version_int($parrot_version) > version_int($config{'VERSION'})) {
$parrot_errors .= "Parrot version $parrot_version required (currently $config{VERSION})\n";
}
}
}

if ($parrot_errors) {
die <<"END";
===SORRY!===
$parrot_errors
To automatically clone (git) and build a copy of parrot $git_describe,
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 Perl.
END
}
my $with_nqp = $options{'with_nqp'};

my $nqp_exe = $parrot_config;
# the .* is needed of somebody has the string 'parrot_config' in
# the build path - we always want to substitute the last occorence
$nqp_exe =~ s/(.*)parrot_config/$1nqp/s;
if (system $nqp_exe, '-e', '') {
die "Cannot execute nqp - maybe try the --gen-nqp option to automatically build one?\n";
# Save options in config.status
unlink('config.status');
if (open(my $CONFIG_STATUS, '>', 'config.status')) {
print $CONFIG_STATUS
"$^X Configure.pl $config{'rakudo_config_status'} \$*\n";
close($CONFIG_STATUS);
}

# 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'};

{
no warnings;
print "Cleaning up ...\n";
if (open my $CLEAN, '-|', "$make clean") {
my @slurp = <$CLEAN>;
close $CLEAN;
}
}

print <<"END";
You can now use '$make' to build Rakudo Perl.
After that, you can use '$make test' to run some local tests,
or '$make spectest' to check out (via git) a copy of the Perl 6
official test suite and run its tests.
END
exit 0;

}


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
my ($nqp_want) = split(' ', slurp('tools/build/NQP_REVISION'));
if (defined $options{'gen-parrot'}) {
$with_nqp = gen_nqp($nqp_want, %options);
}
}

# Generate a Makefile from a configuration
sub create_makefile {
my ($makefile_timing, %config) = @_;

my $maketext = slurp( 'build/Makefile.in' );

$config{'shell'} = $^O eq 'MSWin32' ? 'cmd' : 'sh';
$config{'stagestats'} = $makefile_timing ? '--stagestats' : '';
$config{'win32_libparrot_copy'} = $^O eq 'MSWin32' ? 'copy $(PARROT_BIN_DIR)\libparrot.dll .' : '';
$maketext =~ s/@(\w+)@/$config{$1}/g;
%config = (%config, read_config($with_nqp));
$config{'makefile-timing'} = $options{'makefile-timing'};
$config{'stagestats'} = '--stagestats' if $options{'makefile-timing'};
$config{'shell'} = 'sh';
if ($^O eq 'MSWin32') {
$maketext =~ s{/}{\\}g;
$maketext =~ s{\\\*}{\\\\*}g;
$maketext =~ s{(?:git|http):\S+}{ do {my $t = $&; $t =~ s'\\'/'g; $t} }eg;
$maketext =~ s/.*curl.*/do {my $t = $&; $t =~ s'%'%%'g; $t}/meg;
}

if ($makefile_timing) {
$maketext =~ s{(?<!\\\n)^\t(?!\s*-?cd)(?=[^\n]*\S)}{\ttime }mg;
$config{'shell'} = 'cmd';
$config{'win32_libparrot_copy'} =
'copy $(PARROT_BIN_DIR)\libparrot.dll .';
}

my $outfile = 'Makefile';
print "\nCreating $outfile ...\n";
open(my $MAKEOUT, '>', $outfile) ||
die "Unable to write $outfile\n";
print {$MAKEOUT} $maketext;
close $MAKEOUT or die $!;

return;
}
fill_template_file('tools/build/Makefile.in', 'Makefile', %config);

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
Configure.pl - NQP Configure
General Options:
--help Show this text
--prefix=dir Install files in dir
--with-parrot=path/to/bin/parrot
Parrot executable to use to build NQP
--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
--parrot-option='--option=value'
Options to pass to parrot configuration for --gen-parrot
END

return;
Expand Down
3 changes: 3 additions & 0 deletions build/Makefile.in → tools/build/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,6 @@ $(DYNOPS): $(OPS_DIR)/$(OPS_SOURCE) src/binder/bind.c src/binder/bind.h src/bind
cd src/binder && $(CC) -c @cc_o_out@container$(O) -I../../$(PMC_DIR) $(CINCLUDES) $(CFLAGS) container.c
cd src/binder && $(CC) -c @cc_o_out@types$(O) -I../../$(PMC_DIR) $(CINCLUDES) $(CFLAGS) types.c
cd $(OPS_DIR) && $(LD) @ld_out@$(OPS)$(LOAD_EXT) $(OPS)$(O) ../binder/bind$(O) ../binder/multidispatch$(O) ../binder/container$(O) ../binder/types$(O) $(LINKARGS)

# nqp::makefile <-- tells NQP::Configure to treat this file as a makefile,
# performing win32 slash and makefile conversions
1 change: 1 addition & 0 deletions tools/build/NQP_REVISION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2011.05-36-gc9a6dba
Loading

0 comments on commit 7ec8cf2

Please sign in to comment.