Index: lib/Parrot/Configure/Step/List.pm =================================================================== --- lib/Parrot/Configure/Step/List.pm (.../trunk) (revision 41745) +++ lib/Parrot/Configure/Step/List.pm (.../branches/detect_llvm) (revision 41767) @@ -41,6 +41,7 @@ auto::arch auto::jit auto::frames + auto::llvm auto::cpu auto::cgoto auto::inline Index: MANIFEST =================================================================== --- MANIFEST (.../trunk) (revision 41745) +++ MANIFEST (.../branches/detect_llvm) (revision 41767) @@ -1,7 +1,7 @@ # ex: set ro: # $Id$ # -# generated by tools/dev/mk_manifest_and_skip.pl Wed Sep 30 22:16:16 2009 UT +# generated by tools/dev/mk_manifest_and_skip.pl Wed Oct 7 21:06:54 2009 UT # # See below for documentation on the format of this file. # @@ -257,6 +257,8 @@ config/auto/isreg.pm [] config/auto/isreg/test_c.in [] config/auto/jit.pm [] +config/auto/llvm.pm [] +config/auto/llvm/hello.c [] config/auto/memalign.pm [] config/auto/memalign/test2_c.in [] config/auto/memalign/test_c.in [] @@ -1931,6 +1933,7 @@ t/steps/auto/inline-01.t [test] t/steps/auto/isreg-01.t [test] t/steps/auto/jit-01.t [test] +t/steps/auto/llvm-01.t [test] t/steps/auto/memalign-01.t [test] t/steps/auto/msvc-01.t [test] t/steps/auto/neg_0-01.t [test] Index: t/steps/auto/llvm-01.t =================================================================== --- t/steps/auto/llvm-01.t (.../trunk) (revision 0) +++ t/steps/auto/llvm-01.t (.../branches/detect_llvm) (revision 41767) @@ -0,0 +1,107 @@ +#!perl +# Copyright (C) 2001-2007, Parrot Foundation. +# $Id$ +# auto/llvm-01.t + +use strict; +use warnings; +use Test::More tests => 27; +use Carp; +use lib qw( lib t/configure/testlib ); +use_ok('config::init::defaults'); +use_ok('config::inter::progs'); +use_ok('config::auto::llvm'); +use Parrot::Configure; +use Parrot::Configure::Options qw( process_options ); +use Parrot::Configure::Test qw( + test_step_thru_runstep + rerun_defaults_for_testing + test_step_constructor_and_description +); +use IO::CaptureOutput qw( capture ); + +########## regular ########## + +my ($args, $step_list_ref) = process_options( { + argv => [ ], + mode => q{configure}, +} ); + +my $conf = Parrot::Configure->new; + +my $serialized = $conf->pcfreeze(); + +test_step_thru_runstep($conf, q{init::defaults}, $args); +test_step_thru_runstep($conf, q{inter::progs}, $args); + +my $pkg = q{auto::llvm}; + +$conf->add_steps($pkg); +$conf->options->set( %{$args} ); +my $step = test_step_constructor_and_description($conf); +my $ret = $step->runstep($conf); +ok( $ret, "runstep() returned true value" ); +like( $step->result(), qr/yes|no/, + "Result was either 'yes' or 'no'" ); + +$conf->replenish($serialized); + +########## --verbose ########## + +($args, $step_list_ref) = process_options( { + argv => [ q{--verbose} ], + mode => q{configure}, +} ); +rerun_defaults_for_testing($conf, $args ); +$conf->add_steps($pkg); +$conf->options->set( %{$args} ); +$step = test_step_constructor_and_description($conf); +{ + my $stdout; + my $ret = capture( + sub { $step->runstep($conf) }, + \$stdout + ); + ok( $ret, "runstep() returned true value" ); + like( $step->result(), qr/yes|no/, + "Result was either 'yes' or 'no'" ); + SKIP: { + skip 'No sense testing for verbose output if LLVM not present', + 2 unless ( $step->result() =~ /yes/ ); + like( $stdout, qr/llvm-gcc/s, + "Got expected verbose output" ); + like( $stdout, qr/Low Level Virtual Machine/s, + "Got expected verbose output" ); + } +} + +$conf->cc_clean(); + +pass("Completed all tests in $0"); + +################### DOCUMENTATION ################### + +=head1 NAME + +t/steps/auto/llvm-01.t - tests Parrot::Configure step auto::llvm + +=head1 SYNOPSIS + + prove t/steps/auto/llvm-01.t + +=head1 DESCRIPTION + +This file holds tests for auto::llvm. + +=head1 AUTHOR + +James E Keenan + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: Property changes on: t/steps/auto/llvm-01.t ___________________________________________________________________ Added: svn:eol-style + native Added: svn:mime-type + text/plain Added: svn:keywords + Author Date Id Revision Index: config/auto/llvm.pm =================================================================== --- config/auto/llvm.pm (.../trunk) (revision 0) +++ config/auto/llvm.pm (.../branches/detect_llvm) (revision 41767) @@ -0,0 +1,183 @@ +# Copyright (C) 2009, Parrot Foundation. +# $Id$ + +=head1 NAME + +config/auto/llvm - Check whether the Low Level Virtual Machine is present + +=head1 DESCRIPTION + +Determines whether the Low Level Virtual Machine (LLVM) is installed and +functional on the system. It is OK when it +doesn't exist. + +=cut + +package auto::llvm; + +use strict; +use warnings; + +use base qw(Parrot::Configure::Step); + +use Parrot::Configure::Utils ':auto'; + +sub _init { + my $self = shift; + my %data; + $data{description} = q{Is LLVM installed}; + $data{result} = q{}; + $data{llvm_components} = [ + [ 'llvm-gcc' => 'llvm-gcc' ], + [ 'lli' => 'Low Level Virtual Machine' ], + [ 'llc' => 'Low Level Virtual Machine' ], + ]; + return \%data; +} + +sub runstep { + my ( $self, $conf ) = @_; + + my $verbose = $conf->options->get( 'verbose' ); + + my $llvm_lacking = 0; + foreach my $prog ( @{ $self->{llvm_components} } ) { + my $output = capture_output( $prog->[0], '--version' ); + my $exp = $prog->[1]; + unless ( defined($output) and $output =~ m/$exp/s ) { + $llvm_lacking++; + print "Could not get expected '--version' output for $prog->[0]\n" + if $verbose; + } + else { + print $output, "\n" if $verbose; + } + } + my $output = q{}; + $output = capture_output( 'llvm-gcc', '--version' ); + if (! $output) { + $llvm_lacking++; + } + else { + my @line = split /\n+/, $output; + if ( $line[0] =~ m/\b(\d+)\.(\d+)\.(\d+)\b/ ) { + my @version = ($1, $2, $3); + if ($version[0] < 4) { + print "llvm-gcc must be at least major version 4\n" + if $verbose; + $llvm_lacking++; + } + } + else { + print "Unable to extract llvm-gcc major, minor and patch versions\n" + if $verbose; + $llvm_lacking++; + } + } + + if ( $llvm_lacking ) { + $self->_handle_result( $conf, 0 ); + } + else { + + # Here we will take a simple C file, compile it into an LLVM bitcode + # file, execute it as bitcode, then compile it to native assembly + # using the LLC code generator, then assemble the native assembly + # language file into a program and execute it. Cf.: + # http://llvm.org/releases/2.5/docs/GettingStarted.html#overview + + my $stem = q|hello|; + my $cfile = qq|$stem.c|; + my $fullcfile = qq|config/auto/llvm/$cfile|; + my $bcfile = qq|$stem.bc|; + my $sfile = qq|$stem.s|; + my $nativefile = qq|$stem.native|; + eval { + system(qq{llvm-gcc -O3 -emit-llvm $fullcfile -c -o $bcfile}); + }; + if ($@) { + print "Unable to compile C file into LLVM bitcode file\n" + if $verbose; + $self->_handle_result( $conf, 0 ); + } + else { + my $output; + eval { + $output = capture_output( 'lli', $bcfile ); + }; + if ( $@ or $output !~ /hello world/ ) { + print "Unable to into LLVM bitcode file with 'lli'\n" + if $verbose; + $self->_handle_result( $conf, 0 ); + } + else { + eval { + system(qq{llc $bcfile -o $sfile}); + }; + if ( $@ or (! -e $sfile) ) { + print "Unable to compile program to native assembly using 'llc'\n" + if $verbose; + $self->_handle_result( $conf, 0 ); + } + else { + eval { + my $cc = $conf->data->get('cc'); + system(qq{$cc $sfile -o $nativefile}); + }; + if ( $@ or (! -e $nativefile) ) { + print "Unable to assemble native assembly into program\n" + if $verbose; + $self->_handle_result( $conf, 0 ); + } + else { + eval { + $output = capture_output(qq{./$nativefile}); + }; + if ( $@ or ( $output !~ q/hello world/) ) { + print "Unable to execute native assembly program successfuly\n" + if $verbose; + $self->_handle_result( $conf, 0 ); + } + else { + $self->_handle_result( $conf, 1 ); + } + } + } + } + } + foreach my $f ( $bcfile, $sfile, $nativefile ) { + unlink $f if ( -e $f ); + } + $conf->cc_clean(); + } + + return 1; +} + +sub _handle_result { + my ($self, $conf, $result) = @_; + if ( $result ) { + $self->set_result('yes'); + $conf->data->set( has_llvm => 1 ); + } + else { + $self->set_result('no'); + $conf->data->set( has_llvm => '' ); + } + return 1; +} +1; + +=head1 AUTHOR + +James E Keenan + +=cut + +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# fill-column: 100 +# End: +# vim: expandtab shiftwidth=4: + Property changes on: config/auto/llvm.pm ___________________________________________________________________ Added: svn:eol-style + native Added: svn:keywords + Author Date Id Revision Index: config/auto/llvm/hello.c =================================================================== --- config/auto/llvm/hello.c (.../trunk) (revision 0) +++ config/auto/llvm/hello.c (.../branches/detect_llvm) (revision 41767) @@ -0,0 +1,6 @@ +#include + +int main() { + printf("hello world\n"); + return 0; +} Property changes on: config/auto/llvm/hello.c ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native