X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=ext%2FTime%2FHiRes%2FMakefile.PL;h=5e54b4976d1e3ad0246c6fb20a9b8e88d0d0af49;hb=952306aca140c014b38ba5eb2ed71dffaa548f0f;hp=ea8b85f99359ced400f8a757c4553516b1055f47;hpb=3f2ee0069d15f7a7d413167c0ad86d1545e6b534;p=p5sagit%2Fp5-mst-13.2.git diff --git a/ext/Time/HiRes/Makefile.PL b/ext/Time/HiRes/Makefile.PL index ea8b85f..5e54b49 100644 --- a/ext/Time/HiRes/Makefile.PL +++ b/ext/Time/HiRes/Makefile.PL @@ -1,16 +1,32 @@ - -# See lib/ExtUtils/MakeMaker.pm for details of how to influence -# the contents of the Makefile that is written. +#!/usr/bin/perl # +# In general we trust %Config, but for nanosleep() this trust +# may be misplaced (it may be linkable but not really functional). +# Use $ENV{FORCE_NANOSLEEP_SCAN} to force rescanning whether there +# really is hope. require 5.002; use Config; use ExtUtils::MakeMaker; - -# Perls 5.002 and 5.003 did not have File::Spec, fake what we need. +use strict; my $VERBOSE = $ENV{VERBOSE}; +my $DEFINE; +my $LIBS = []; +my $XSOPT = ''; +my $SYSCALL_H; + +use vars qw($self); # Used in 'sourcing' the hints. + +my $ld_exeext = ($^O eq 'cygwin' || + $^O eq 'os2' && $Config{ldflags} =~ /-Zexe\b/) ? '.exe' : ''; + +unless($ENV{PERL_CORE}) { + $ENV{PERL_CORE} = 1 if grep { $_ eq 'PERL_CORE=1' } @ARGV; +} + +# Perls 5.002 and 5.003 did not have File::Spec, fake what we need. sub my_dirsep { $^O eq 'VMS' ? '.' : @@ -22,7 +38,14 @@ sub my_dirsep { sub my_catdir { shift; my $catdir = join(my_dirsep, @_); - $^O eq 'VMS' ? "[$dirsep]" : $dirsep; + $^O eq 'VMS' ? "[$catdir]" : $catdir; +} + +sub my_catfile { + shift; + return join(my_dirsep, @_) unless $^O eq 'VMS'; + my $file = pop; + return my_catdir (undef, @_) . $file; } sub my_updir { @@ -33,33 +56,30 @@ sub my_updir { BEGIN { eval { require File::Spec }; if ($@) { - *File::Spec::catdir = \&my_catdir; - *File::Spec::updir = \&my_updir; + *File::Spec::catdir = \&my_catdir; + *File::Spec::updir = \&my_updir; + *File::Spec::catfile = \&my_catfile; } } +# Avoid 'used only once' warnings. +my $nop1 = *File::Spec::catdir; +my $nop2 = *File::Spec::updir; +my $nop3 = *File::Spec::catfile; + # if you have 5.004_03 (and some slightly older versions?), xsubpp # tries to generate line numbers in the C code generated from the .xs. # unfortunately, it is a little buggy around #ifdef'd code. -# my choice is leave it in and have people with old perls complain +# my choice is leave it in and have people with old perls complain # about the "Usage" bug, or leave it out and be unable to compile myself -# without changing it, and then I'd always forget to change it before a +# without changing it, and then I'd always forget to change it before a # release. Sorry, Edward :) -sub TMPDIR { - my $TMPDIR = - (grep(defined $_ && -d $_ && -w _, - ((defined $ENV{'TMPDIR'} ? $ENV{'TMPDIR'} : undef), - qw(/var/tmp /usr/tmp /tmp))))[0] - unless defined $TMPDIR; - $TMPDIR || die "Cannot find writable temporary directory.\n"; -} - sub try_compile_and_link { my ($c, %args) = @_; my ($ok) = 0; - my ($tmp) = (($^O eq 'VMS') ? "sys\$scratch:tmp$$" : TMPDIR . '/' . "tmp$$"); + my ($tmp) = "tmp$$"; local(*TMPC); my $obj_ext = $Config{obj_ext} || ".o"; @@ -69,25 +89,30 @@ sub try_compile_and_link { print TMPC $c; close(TMPC); - $cccmd = $args{cccmd}; + my $cccmd = $args{cccmd}; my $errornull; my $COREincdir; + if ($ENV{PERL_CORE}) { my $updir = File::Spec->updir; $COREincdir = File::Spec->catdir(($updir) x 3); } else { $COREincdir = File::Spec->catdir($Config{'archlibexp'}, 'CORE'); } + my $ccflags = $Config{'ccflags'} . ' ' . "-I$COREincdir"; + if ($^O eq 'VMS') { if ($ENV{PERL_CORE}) { - $cccmd = "$Config{'cc'} /include=(perl_root:[000000]) $tmp.c"; + # Fragile if the extensions change hierarchy within + # the Perl core but this should do for now. + $cccmd = "$Config{'cc'} /include=([---]) $tmp.c"; } else { my $perl_core = $Config{'installarchlib'}; $perl_core =~ s/\]$/.CORE]/; - $cccmd = "$Config{'cc'} /include=(perl_root:[000000],$perl_core) $tmp.c"; + $cccmd = "$Config{'cc'} /include=(perl_root:[000000],$perl_core) $tmp.c"; } } @@ -97,40 +122,61 @@ sub try_compile_and_link { $errornull = ''; } - $cccmd = "$Config{'cc'} -o $tmp $ccflags $tmp.c @$LIBS $errornull" + $cccmd = "$Config{'cc'} -o $tmp $ccflags $tmp.c @$LIBS $errornull" unless defined $cccmd; - if ($^O eq 'VMS') { + + if ($^O eq 'VMS') { open( CMDFILE, ">$tmp.com" ); print CMDFILE "\$ SET MESSAGE/NOFACILITY/NOSEVERITY/NOIDENT/NOTEXT\n"; print CMDFILE "\$ $cccmd\n"; - print CMDFILE "\$ IF \$SEVERITY .NE. 1 THEN EXIT 44\n"; # escalate + print CMDFILE "\$ IF \$SEVERITY .NE. 1 THEN EXIT 44\n"; # escalate close CMDFILE; system("\@ $tmp.com"); $ok = $?==0; - for ("$tmp.c", "$tmp$obj_ext", "$tmp.com", "$tmp$Config{exe_ext}") { - 1 while unlink $_; + for ("$tmp.c", "$tmp$obj_ext", "$tmp.com", "$tmp$Config{exe_ext}") { + 1 while unlink $_; } } else { + my $tmp_exe = "$tmp$ld_exeext"; printf "cccmd = $cccmd\n" if $VERBOSE; - system($cccmd); - $ok = -s $tmp && -x _; - unlink("$tmp.c", $tmp); + my $res = system($cccmd); + $ok = defined($res) && $res == 0 && -s $tmp_exe && -x _; + + if ( $ok && exists $args{run} && $args{run}) { + my $tmp_exe = + File::Spec->catfile(File::Spec->curdir, $tmp_exe); + printf "Running $tmp_exe..." if $VERBOSE; + if (system($tmp_exe) == 0) { + $ok = 1; + } else { + $ok = 0; + my $errno = $? >> 8; + local $! = $errno; + printf < -DHAS_GETTIMEOFDAY already) - return 0 if $Config{'d_gettimeod'} eq 'define'; - return 1 if try_compile_and_link(< #endif @@ -155,7 +201,7 @@ EOM } sub has_x { - my ($x, %args) = @_; + my ($x, %args) = @_; return 1 if try_compile_and_link(< 1); +#include +#include +#include +#include +#include + +/* int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); */ + +int main() { + struct timespec ts1, ts2; + int ret; + ts1.tv_sec = 0; + ts1.tv_nsec = 750000000; + ts2.tv_sec = 0; + ts2.tv_nsec = 0; + errno = 0; + ret = nanosleep(&ts1, &ts2); /* E.g. in AIX nanosleep() fails and sets errno to ENOSYS. */ + ret == 0 ? exit(0) : exit(errno ? errno : -1); +} +EOM +} - $LIBS = []; +sub has_include { + my ($inc) = @_; + return 1 if + try_compile_and_link(< +int main _((int argc, char** argv, char** env)) +{ + return 0; +} +EOM + return 0; +} - # ... but ucb is poison for Solaris, and probably Linux. honest. - $LIBS = [] if $Config{'osname'} eq 'solaris'; - $LIBS = [] if $Config{'osname'} eq 'linux'; - $LIBS = ['-lm'] if $Config{'osname'} =~ /sco/i; - $LIBS = ['-lc'] if $Config{'osname'} =~ /dynixptx/i; +sub has_clock_xxx_syscall { + my $x = shift; + return 0 unless defined $SYSCALL_H; + return 1 if + try_compile_and_link(< 1); +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +#include <$SYSCALL_H> +int main _((int argc, char** argv, char** env)) +{ + struct timespec ts; + /* Many Linuxes get ENOSYS even though the syscall exists. */ + /* All implementations are supposed to support CLOCK_REALTIME. */ + int ret = syscall(SYS_clock_$x, CLOCK_REALTIME, &ts); + ret == 0 ? exit(0) : exit(errno ? errno : -1); +} +EOM +} - # For nanosleep - push @$LIBS, '-lrt' unless $Config{'osname'} =~ /irix/; - push @$LIBS, '-lposix4' ; +sub has_clock_xxx { + my $xxx = shift; + return 1 if + try_compile_and_link(< 1); +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +int main _((int argc, char** argv, char** env)) +{ + struct timespec ts; + int ret = clock_$xxx(CLOCK_REALTIME, &ts); /* Many Linuxes get ENOSYS. */ + /* All implementations are supposed to support CLOCK_REALTIME. */ + ret == 0 ? exit(0) : exit(errno ? errno : -1); +} +EOM +} - my @goodlibs; +sub has_clock { + return 1 if + try_compile_and_link(< 1); +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +int main _((int argc, char** argv, char** env)) +{ + clock_t tictoc; + clock_t ret = clock(); + ret == (clock_t)-1 ? exit(errno ? errno : -1) : exit(0); +} +EOM +} - select(STDOUT); $| = 1; +sub has_clock_nanosleep { + return 1 if + try_compile_and_link(< 1); +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +int main _((int argc, char** argv, char** env)) +{ + int ret; + struct timerspec ts1; + struct timerspec ts2; + ts1.tv_sec = 0; + ts1.tv_nsec = 750000000;; + ret = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts1, &ts2); + ret == 0 ? exit(0) : exit(errno ? errno : -1); +} +EOM +} + +sub init { + my $hints = File::Spec->catfile("hints", "$^O.pl"); + if (-f $hints) { + print "Using hints $hints...\n"; + local $self; + do $hints; + if (exists $self->{LIBS}) { + $LIBS = $self->{LIBS}; + print "Extra libraries: @$LIBS...\n"; + } + } + + $DEFINE = ''; - print "Checking for libraries...\n"; - my $lib; - for $lib (@$LIBS) { - print "Checking for $lib...\n"; - $LIBS = [ $lib ]; - if ($Config{libs} =~ /\b$lib\b/ || has_x("time(0)")) { - push @goodlibs, $lib; + if ($Config{d_syscall}) { + print "Have syscall()... looking for syscall.h... "; + if (has_include('syscall.h')) { + $SYSCALL_H = 'syscall.h'; + } elsif (has_include('sys/syscall.h')) { + $SYSCALL_H = 'sys/syscall.h'; } + } else { + print "No syscall()...\n"; } - @$LIBS = @goodlibs; - print @$LIBS ? - "You have extra libraries: @$LIBS.\n" : - "You have no applicable extra libraries.\n"; - print "\n"; - print "Looking for gettimeofday()...\n"; + if ($Config{d_syscall}) { + if (defined $SYSCALL_H) { + print "found <$SYSCALL_H>.\n"; + } else { + print "NOT found.\n"; + } + } + + print "Looking for gettimeofday()... "; my $has_gettimeofday; - if ($Config{'d_gettimeod'}) { - $has_gettimeofday++; + if (exists $Config{d_gettimeod}) { + $has_gettimeofday++ if $Config{d_gettimeod}; } elsif (has_gettimeofday()) { $DEFINE .= ' -DHAS_GETTIMEOFDAY'; $has_gettimeofday++; } if ($has_gettimeofday) { - print "You have gettimeofday().\n\n"; + print "found.\n"; } else { die <... "; + if (has_include('w32api/windows.h')) { + $has_w32api_windows_h++; + $DEFINE .= ' -DHAS_W32API_WINDOWS_H'; + } + if ($has_w32api_windows_h) { + print "found.\n"; + } else { + print "NOT found.\n"; + } } if ($DEFINE) { @@ -347,7 +614,7 @@ EOD } sub doMakefile { - @makefileopts = (); + my @makefileopts = (); if ($] >= 5.005) { push (@makefileopts, @@ -360,47 +627,101 @@ sub doMakefile { push (@makefileopts, 'NAME' => 'Time::HiRes', 'VERSION_FROM' => 'HiRes.pm', # finds $VERSION - 'LIBS' => $LIBS, # e.g., '-lm' - 'DEFINE' => $DEFINE, # e.g., '-DHAS_SOMETHING' + 'LIBS' => $LIBS, # e.g., '-lm' + 'DEFINE' => $DEFINE, # e.g., '-DHAS_SOMETHING' 'XSOPT' => $XSOPT, - # do not even think about 'INC' => '-I/usr/ucbinclude', Solaris will avenge. - 'INC' => '', # e.g., '-I/usr/include/other' - 'INSTALLDIRS' => 'perl', + # Do not even think about 'INC' => '-I/usr/ucbinclude', + # Solaris will avenge. + 'INC' => '', # e.g., '-I/usr/include/other' + 'INSTALLDIRS' => ($] >= 5.008 ? 'perl' : 'site'), 'dist' => { 'CI' => 'ci -l', - 'COMPRESS' => 'gzip -9f', + 'COMPRESS' => 'gzip -9f', 'SUFFIX' => 'gz', }, clean => { FILES => "xdefine" }, + realclean => { FILES=> 'const-c.inc const-xs.inc' }, ); + if ($ENV{PERL_CORE}) { + push @makefileopts, MAN3PODS => {}; + } + WriteMakefile(@makefileopts); } -sub main { - print < $_, macro => $macro, value => 1, + default => ["IV", "0"]}; + } + ExtUtils::Constant::WriteConstants( + NAME => 'Time::HiRes', + NAMES => \@names, + ); + } else { + my $file; + foreach $file ('const-c.inc', 'const-xs.inc') { + my $fallback = File::Spec->catfile('fallback', $file); + local $/; + open IN, "<$fallback" or die "Can't open $fallback: $!"; + open OUT, ">$file" or die "Can't open $file: $!"; + print OUT or die $!; + close OUT or die "Can't close $file: $!"; + close IN or die "Can't close $fallback: $!"; + } + } +} -EOM +sub main { + print "Configuring Time::HiRes...\n"; + if ($] == 5.007002) { + die "Cannot Configure Time::HiRes for Perl $], aborting.\n"; + } if ($^O =~ /Win32/i) { $DEFINE = '-DSELECT_IS_BROKEN'; - $LIBS = ['']; + $LIBS = []; + print "System is $^O, skipping full configure...\n"; } else { - unixinit(); + init(); } - configure; doMakefile; + doConstants; my $make = $Config{'make'} || "make"; - unless ($ENV{PERL_CORE}) { + unless (exists $ENV{PERL_CORE} && $ENV{PERL_CORE}) { print <