Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[GH #853] Enable proper llvm probes

enable compilation probes
add the --llvm-config option and handle it
print the detected version (silent 1 as fallback)
detect static llvm libs
handle the debian testing default case (appended -version)
handle the llvm 3.2 new --version format
set proper llvm_{c,cxx,ld}flags and llvm_libs config keys for opsc_llvm integration
try given cc for a llvm-gcc or clang compatible compiler
check the output of -emit-llvm by file magic inspection
  ld: warning: cannot find entry symbol 'mit-llvm'
  • Loading branch information...
commit 132f7c760d0f4cc119668be40f38d2d1ccfa9524 1 parent 87ac5ce
@rurban rurban authored
View
105 config/auto/llvm.pm
@@ -46,13 +46,21 @@ sub runstep {
# runstep() with a value of 1. If a given probe does not rule out LLVM,
# we will proceed onward.
- my ($llvm_bindir, $llvm_config);
- for my $bin (qw(llvm-config llvm-config-3.0 llvm-config-2.9 llvm-config-2.8)) {
- $llvm_bindir = capture_output( $bin, "--bindir" ) || '';
+ my $llvm_config = $conf->options->get( 'llvm-config' );
+ my $llvm_bindir;
+ if ( $llvm_config and -e "$llvm_config" ) {
+ $llvm_bindir = capture_output( $llvm_config, "--bindir" ) || '';
chomp $llvm_bindir;
- if ( $llvm_bindir ) {
- $llvm_config = $bin;
- last;
+ }
+ else {
+ for my $ver ('',qw(-3.2 -3.1 -3.0 -2.9 -2.8 -2.7)) {
+ my $bin = 'llvm-config'.$ver;
+ $llvm_bindir = capture_output( $bin, "--bindir" ) || '';
+ chomp $llvm_bindir;
+ if ( $llvm_bindir ) {
+ $llvm_config = $bin;
+ last;
+ }
}
}
if (! $llvm_bindir ) {
@@ -65,20 +73,25 @@ sub runstep {
chomp(@output = `"$llvm_bindir/lli" --version`);
my $rv = $self->version_check($conf, \@output, $verbose);
return 1 unless $rv;
+ my $version = $rv;
- # Find lib
- my $ldd = `ldd "$llvm_bindir/lli"`;
- if ($ldd =~ /(libLLVM[^ ]+)(.*)/m){
- my $lib = $1;
- my $path = (split(' ',$2))[1];
- $conf->data->set( llvm_shared => $path );
- if ($lib =~ /lib(LLVM.*)\.(so|dll)/){
- $conf->data->set( llvm_ldflags => "-l$1" );
- }
+ # Find flags
+ my ($cflags, $cxxflags, $ldflags, $libs);
+ if ($ldflags = $self->_llvm_config($llvm_config, '--ldflags')) {
+ $conf->data->set( llvm_ldflags => $ldflags );
+ }
+ if ($libs = $self->_llvm_config($llvm_config, '--libs')) {
+ $conf->data->set( llvm_libs => $libs );
+ }
+ if ($cflags = $self->_llvm_config($llvm_config, '--cflags')) {
+ $conf->data->set( llvm_cflags => $cflags );
+ }
+ if ($cxxflags = $self->_llvm_config($llvm_config, '--cxxflags')) {
+ $conf->data->set( llvm_cxxflags => $cxxflags );
}
- $self->_handle_result($conf, $rv);
- return 1;
+ # $self->_handle_result($conf, $version);
+ # return 1;
# Having gotten this far, we will take a simple C file, compile it into
# an LLVM bitcode file, execute it as bitcode, then compile it to native
@@ -92,11 +105,22 @@ sub runstep {
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});
- };
- $rv = '';
- if ($@) {
+ unlink $bcfile;
+ for my $cc ($conf->data->get('cc'),
+ "$llvm_bindir/clang", "$llvm_bindir/llvm-gcc",
+ qw(llvm-gcc clang))
+ {
+ # Note: gcc and g++ with -c just skips over -emit-llvm and produce native code
+ # without -c: ld: warning: cannot find entry symbol 'mit-llvm'
+ eval {
+ system(qq{$cc -emit-llvm -O3 $fullcfile -c -o $bcfile});
+ };
+ if (!$@ and -e $bcfile and $self->_check_bcfile($bcfile)) {
+ $conf->data->set( llvm_gcc => $cc );
+ last;
+ }
+ }
+ if (! $conf->data->get( 'llvm_gcc' )) {
$rv = $self->_handle_failure_to_compile_into_bitcode(
$conf,
$verbose,
@@ -109,7 +133,7 @@ sub runstep {
else {
my $output;
eval {
- $output = capture_output( 'lli', $bcfile );
+ $output = capture_output( "$llvm_bindir/lli", $bcfile );
};
if ( $@ or $output !~ /hello world/ ) {
$rv = $self->_handle_failure_to_execute_bitcode( $conf, $verbose );
@@ -120,7 +144,7 @@ sub runstep {
}
else {
eval {
- system(qq{llc $bcfile -o $sfile});
+ system(qq{"$llvm_bindir/llc" $bcfile -o $sfile});
};
if ( $@ or (! -e $sfile) ) {
$rv = $self->_handle_failure_to_compile_to_assembly(
@@ -152,7 +176,7 @@ sub runstep {
$output = capture_output(qq{./$nativefile});
};
$self->_handle_native_assembly_output(
- $conf, $output, $verbose
+ $conf, $output, $verbose, $version
);
}
}
@@ -166,10 +190,26 @@ sub runstep {
return 1;
}
+sub _check_bcfile {
+ my ($self, $bcfile) = @_;
+ open my $fh, '<', $bcfile or return;
+ my $read = read $fh, my $bytes, 2;
+ my $result = 1 if $read == 2 and $bytes eq 'BC';
+ close $fh;
+ return $result;
+}
+
+sub _llvm_config {
+ my ($self, $llvm_config, $arg) = @_;
+ my $result = `"$llvm_config" $arg`;
+ chomp $result;
+ return $result;
+}
+
sub version_check {
my ($self, $conf, $outputref, $verbose) = @_;
my $version;
- if ( $outputref->[1] =~ m/llvm\sversion\s(\d+\.\d+)/s ) {
+ if ( $outputref->[1] =~ m/llvm\sversion\s(\d+\.\d+)/is ) {
$version = $1;
if ($version < $self->{lli_min_version}) {
if ($verbose) {
@@ -227,7 +267,12 @@ sub _handle_failure_to_assemble_assembly {
sub _handle_result {
my ($self, $conf, $result) = @_;
if ( $result ) {
- $self->set_result( "yes" );
+ if ($result == 1) {
+ $self->set_result( "yes" );
+ }
+ else {
+ $self->set_result( "yes, ".$result );
+ }
$conf->data->set( has_llvm => 1 );
}
else {
@@ -238,14 +283,14 @@ sub _handle_result {
}
sub _handle_native_assembly_output {
- my ($self, $conf, $output, $verbose) = @_;
+ my ($self, $conf, $output, $verbose, $rv) = @_;
if ( $@ or ( $output !~ /hello world/ ) ) {
print "Unable to execute native assembly program successfully\n"
if $verbose;
$self->_handle_result( $conf, 0 );
}
else {
- $self->_handle_result( $conf, 1 );
+ $self->_handle_result( $conf, $rv );
}
}
@@ -265,7 +310,7 @@ sub _cleanup_llvm_files {
=head1 AUTHOR
-James E Keenan
+James E Keenan, Reini Urban
=cut
View
3  lib/Parrot/Configure/Options/Conf/Shared.pm
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2009, Parrot Foundation.
+# Copyright (C) 2007-2012, Parrot Foundation.
package Parrot::Configure::Options::Conf::Shared;
use strict;
@@ -47,6 +47,7 @@ our @shared_valid_options = qw{
libs
link
linkflags
+ llvm-config
localstatedir
m
make
View
15 t/steps/auto/llvm-01.t
@@ -1,11 +1,11 @@
#!perl
-# Copyright (C) 2001-2011, Parrot Foundation.
+# Copyright (C) 2001-2012, Parrot Foundation.
# auto/llvm-01.t
use strict;
use warnings;
use File::Temp qw( tempdir );
-use Test::More tests => 56;
+use Test::More tests => 58;
use Carp;
use lib qw( lib t/configure/testlib );
use_ok('config::auto::llvm');
@@ -252,12 +252,21 @@ my $output = '';
local $@ = '';
$output = 'hello world';
$verbose = 0;
- ok( $step->_handle_native_assembly_output( $conf, $output, $verbose ),
+ ok( $step->_handle_native_assembly_output( $conf, $output, $verbose, 1 ),
"_handle_native_assembly_output() returned true value" );
is( $step->result(), 'yes', "Got expected 'yes' result" );
}
{
+ local $@ = '';
+ $output = 'hello world';
+ $verbose = 0;
+ ok( $step->_handle_native_assembly_output( $conf, $output, $verbose, 2.7 ),
+ "_handle_native_assembly_output() returned true value" );
+ is( $step->result(), 'yes, 2.7', "Got expected 'yes' result" );
+}
+
+{
local $@ = 'error';
$output = 'hello world';
$verbose = 0;
Please sign in to comment.
Something went wrong with that request. Please try again.