From: Graham Knop Date: Mon, 6 Jan 2014 08:27:54 +0000 (-0500) Subject: better compiler check X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=615c05b0c2805bf268d8503572a47b64c6cbe062;p=p5sagit%2Fstrictures.git better compiler check --- diff --git a/Makefile.PL b/Makefile.PL index cfb4e6d..2caeffd 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -1,6 +1,21 @@ use strict; use warnings FATAL => 'all'; use ExtUtils::MakeMaker; +BEGIN { if ( $^O eq 'cygwin' ) { + require ExtUtils::MM_Cygwin; + require ExtUtils::MM_Win32; + if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) { + *ExtUtils::MM_Cygwin::maybe_command = sub { + my ($self, $file) = @_; + if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) { + ExtUtils::MM_Win32->maybe_command($file); + } else { + ExtUtils::MM_Unix->maybe_command($file); + } + } + } +}} + (do 'maint/Makefile.PL.include' or die $@) unless -f 'META.yml'; @@ -23,8 +38,7 @@ sub parse_args { my $have_compiler = ! parse_args()->{PUREPERL_ONLY} - && eval { require ExtUtils::CBuilder; 1 } - && ExtUtils::CBuilder->new->have_compiler; + && can_xs(); WriteMakefile( NAME => 'strictures', @@ -64,3 +78,102 @@ WriteMakefile( ($] >= 5.008004 && $have_compiler ? ( PREREQ_PM => \%extra_prereqs ) : () ), ); + +# can we locate a (the) C compiler +sub can_cc { + my @chunks = split(/ /, $Config::Config{cc}) or return; + + # $Config{cc} may contain args; try to find out the program part + while (@chunks) { + return can_run("@chunks") || (pop(@chunks), next); + } + + return; +} + +# check if we can run some command +sub can_run { + my ($cmd) = @_; + + return $cmd if -x $cmd; + if (my $found_cmd = MM->maybe_command($cmd)) { + return $found_cmd; + } + + require File::Spec; + for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') { + next if $dir eq ''; + my $abs = File::Spec->catfile($dir, $cmd); + return $abs if (-x $abs or $abs = MM->maybe_command($abs)); + } + + return; +} + +# Can our C compiler environment build XS files +sub can_xs { + # Do we have the configure_requires checker? + local $@; + eval "require ExtUtils::CBuilder; ExtUtils::CBuilder->VERSION(0.27)"; + if ( $@ ) { + # They don't obey configure_requires, so it is + # someone old and delicate. Try to avoid hurting + # them by falling back to an older simpler test. + return can_cc(); + } + + # Do we have a working C compiler + my $builder = ExtUtils::CBuilder->new( + quiet => 1, + ); + unless ( $builder->have_compiler ) { + # No working C compiler + return 0; + } + + # Write a C file representative of what XS becomes + require File::Temp; + my ( $FH, $tmpfile ) = File::Temp::tempfile( + "compilexs-XXXXX", + SUFFIX => '.c', + ); + binmode $FH; + print $FH <<'END_C'; +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +int main(int argc, char **argv) { + return 0; +} + +int boot_sanexs() { + return 1; +} + +END_C + close $FH; + + # Can the C compiler access the same headers XS does + my @libs = (); + my $object = undef; + eval { + local $^W = 0; + $object = $builder->compile( + source => $tmpfile, + ); + @libs = $builder->link( + objects => $object, + module_name => 'sanexs', + ); + }; + my $result = $@ ? 0 : 1; + + # Clean up all the build files + foreach ( $tmpfile, $object, @libs ) { + next unless defined $_; + 1 while unlink; + } + + return $result; +}