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=20717920180531f5d560e30843ed9b043469a4a7;hpb=a0c8e3cf5fa0fae52f31f219ff170d986966c18e;p=p5sagit%2Fp5-mst-13.2.git diff --git a/ext/Time/HiRes/Makefile.PL b/ext/Time/HiRes/Makefile.PL index 2071792..5e54b49 100644 --- a/ext/Time/HiRes/Makefile.PL +++ b/ext/Time/HiRes/Makefile.PL @@ -1,7 +1,9 @@ - -# 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; @@ -11,11 +13,17 @@ use strict; my $VERBOSE = $ENV{VERBOSE}; my $DEFINE; -my $LIBS; -my $XSOPT; +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}) { # This trick from Encode/Makefile.PL. - $ENV{PERL_CORE} = 1 if ($^X =~ m{\bminiperl[^/\\\]>:]*$}o); +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. @@ -48,8 +56,8 @@ 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; } } @@ -62,24 +70,16 @@ 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 c:/temp))))[0]; - $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"; @@ -106,7 +106,7 @@ sub try_compile_and_link { if ($^O eq 'VMS') { if ($ENV{PERL_CORE}) { - # Fragile if the extensions change hierachy within + # Fragile if the extensions change hierarchy within # the Perl core but this should do for now. $cccmd = "$Config{'cc'} /include=([---]) $tmp.c"; } else { @@ -125,7 +125,7 @@ sub try_compile_and_link { $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"; @@ -133,30 +133,50 @@ sub try_compile_and_link { close CMDFILE; system("\@ $tmp.com"); $ok = $?==0; - for ("$tmp.c", "$tmp$obj_ext", "$tmp.com", "$tmp$Config{exe_ext}") { + 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 0 if $Config{d_gettimeod}; return 1 if try_compile_and_link(< #endif @@ -209,51 +229,157 @@ EOM return 0; } -sub unixinit { - $DEFINE = ''; +sub has_nanosleep { + print "testing... "; + 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 +} - print "Checking for libraries...\n"; - my $lib; - for $lib (@$LIBS) { - print "Checking for $lib... "; - $LIBS = [ $lib ]; - if ($Config{libs} =~ /\b$lib\b/ || has_x("time(0)")) { - push @goodlibs, $lib; - print "found.\n"; +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 = ''; + + 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"; + } + + if ($Config{d_syscall}) { + if (defined $SYSCALL_H) { + print "found <$SYSCALL_H>.\n"; } else { print "NOT found.\n"; } } - $LIBS = [ @goodlibs ]; - print @$LIBS ? - "You have extra libraries: @$LIBS.\n" : - "You have no applicable extra libraries.\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++; @@ -277,8 +403,8 @@ EOD print "Looking for setitimer()... "; my $has_setitimer; - if ($Config{d_setitimer}) { - $has_setitimer++; + if (exists $Config{d_setitimer}) { + $has_setitimer++ if $Config{d_setitimer}; } elsif (has_x("setitimer(ITIMER_REAL, 0, 0)")) { $has_setitimer++; $DEFINE .= ' -DHAS_SETITIMER'; @@ -292,8 +418,8 @@ EOD print "Looking for getitimer()... "; my $has_getitimer; - if ($Config{d_getitimer}) { - $has_getitimer++; + if (exists $Config{'d_getitimer'}) { + $has_getitimer++ if $Config{'d_getitimer'}; } elsif (has_x("getitimer(ITIMER_REAL, 0)")) { $has_getitimer++; $DEFINE .= ' -DHAS_GETITIMER'; @@ -306,15 +432,15 @@ EOD } if ($has_setitimer && $has_getitimer) { - print "You have interval timers (both setitimer and setitimer).\n"; + print "You have interval timers (both setitimer and getitimer).\n"; } else { print "You do not have interval timers.\n"; } print "Looking for ualarm()... "; my $has_ualarm; - if ($Config{d_ualarm}) { - $has_ualarm++; + if (exists $Config{d_ualarm}) { + $has_ualarm++ if $Config{d_ualarm}; } elsif (has_x ("ualarm (0, 0)")) { $has_ualarm++; $DEFINE .= ' -DHAS_UALARM'; @@ -332,8 +458,8 @@ EOD print "Looking for usleep()... "; my $has_usleep; - if ($Config{d_usleep}) { - $has_usleep++; + if (exists $Config{d_usleep}) { + $has_usleep++ if $Config{d_usleep}; } elsif (has_x ("usleep (0)")) { $has_usleep++; $DEFINE .= ' -DHAS_USLEEP'; @@ -344,7 +470,7 @@ EOD } else { print "NOT found.\n"; print "Let's see if you have select()... "; - if ($Config{'d_select'} eq 'define') { + if ($Config{'d_select'}) { print "found.\n"; print "We can make a Time::HiRes::usleep().\n"; } else { @@ -355,19 +481,127 @@ EOD print "Looking for nanosleep()... "; my $has_nanosleep; - if ($Config{d_nanosleep}) { - $has_nanosleep++; - } elsif (has_x ("nanosleep (NULL, NULL)")) { - $has_nanosleep++; - $DEFINE .= ' -DHAS_NANOSLEEP'; + if ($ENV{FORCE_NANOSLEEP_SCAN}) { + print "forced scan... "; + if (has_nanosleep()) { + $has_nanosleep++; + $DEFINE .= ' -DTIME_HIRES_NANOSLEEP'; + } + } + elsif (exists $Config{d_nanosleep}) { + print "believing \$Config{d_nanosleep}... "; + if ($Config{d_nanosleep}) { + $has_nanosleep++; + $DEFINE .= ' -DTIME_HIRES_NANOSLEEP'; + } + } elsif ($^O =~ /^(mpeix)$/) { + # MPE/iX falsely finds nanosleep from its libc equivalent. + print "skipping because in $^O... "; + } else { + if (has_nanosleep()) { + $has_nanosleep++; + $DEFINE .= ' -DTIME_HIRES_NANOSLEEP'; + } } if ($has_nanosleep) { print "found.\n"; - print "You can mix subsecond sleeps with signals.\n"; + print "You can mix subsecond sleeps with signals, if you want to.\n"; + print "(It's still not portable, though.)\n"; + } else { + print "NOT found.\n"; + my $nt = ($^O eq 'os2' ? '' : 'not'); + print "You can$nt mix subsecond sleeps with signals.\n"; + print "(It would not be portable anyway.)\n"; + } + + print "Looking for clock_gettime()... "; + my $has_clock_gettime; + if (exists $Config{d_clock_gettime}) { + $has_clock_gettime++ if $Config{d_clock_gettime}; # Unlikely... + } elsif (has_clock_xxx('gettime')) { + $has_clock_gettime++; + $DEFINE .= ' -DTIME_HIRES_CLOCK_GETTIME'; + } elsif (defined $SYSCALL_H && has_clock_xxx_syscall('gettime')) { + $has_clock_gettime++; + $DEFINE .= ' -DTIME_HIRES_CLOCK_GETTIME -DTIME_HIRES_CLOCK_GETTIME_SYSCALL'; + } + + if ($has_clock_gettime) { + if ($DEFINE =~ /-DTIME_HIRES_CLOCK_GETTIME_SYSCALL/) { + print "found (via syscall).\n"; + } else { + print "found.\n"; + } } else { print "NOT found.\n"; - print "You cannot mix subsecond sleeps with signals.\n"; + } + + print "Looking for clock_getres()... "; + my $has_clock_getres; + if (exists $Config{d_clock_getres}) { + $has_clock_getres++ if $Config{d_clock_getres}; # Unlikely... + } elsif (has_clock_xxx('getres')) { + $has_clock_getres++; + $DEFINE .= ' -DTIME_HIRES_CLOCK_GETRES'; + } elsif (defined $SYSCALL_H && has_clock_xxx_syscall('getres')) { + $has_clock_getres++; + $DEFINE .= ' -DTIME_HIRES_CLOCK_GETRES -DTIME_HIRES_CLOCK_GETRES_SYSCALL'; + } + + if ($has_clock_getres) { + if ($DEFINE =~ /-DTIME_HIRES_CLOCK_GETRES_SYSCALL/) { + print "found (via syscall).\n"; + } else { + print "found.\n"; + } + } else { + print "NOT found.\n"; + } + + print "Looking for clock_nanosleep()... "; + my $has_clock_nanosleep; + if (exists $Config{d_clock_nanosleep}) { + $has_clock_nanosleep++ if $Config{d_clock_nanosleep}; # Unlikely... + } elsif (has_clock_nanosleep()) { + $has_clock_nanosleep++; + $DEFINE .= ' -DTIME_HIRES_CLOCK_NANOSLEEP'; + } + + if ($has_clock_nanosleep) { + print "found.\n"; + } else { + print "NOT found.\n"; + } + + print "Looking for clock()... "; + my $has_clock; + if (exists $Config{d_clock}) { + $has_clock++ if $Config{d_clock}; # Unlikely... + } elsif (has_clock()) { + $has_clock++; + $DEFINE .= ' -DTIME_HIRES_CLOCK'; + } + + if ($has_clock) { + print "found.\n"; + } else { + print "NOT found.\n"; + } + + my $has_w32api_windows_h; + + if ($^O eq 'cygwin') { + print "Looking for ... "; + 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) { @@ -393,32 +627,50 @@ 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'}, + realclean => { FILES=> 'const-c.inc const-xs.inc' }, ); + if ($ENV{PERL_CORE}) { + push @makefileopts, MAN3PODS => {}; + } + WriteMakefile(@makefileopts); } sub doConstants { if (eval {require ExtUtils::Constant; 1}) { - my @names = (qw(ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF - ITIMER_REALPROF)); + my @names = (qw(CLOCK_HIGHRES CLOCK_MONOTONIC + CLOCK_PROCESS_CPUTIME_ID + CLOCK_REALTIME + CLOCK_SOFTTIME + CLOCK_THREAD_CPUTIME_ID + CLOCK_TIMEOFDAY + CLOCKS_PER_SEC + ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF + ITIMER_REALPROF + TIMER_ABSTIME)); foreach (qw (d_usleep d_ualarm d_gettimeofday d_getitimer d_setitimer - d_nanosleep)) { + d_nanosleep d_clock_gettime d_clock_getres + d_clock d_clock_nanosleep)) { my $macro = $_; - $macro =~ s/d_(.*)/HAS_\U$1/; + if ($macro =~ /^(d_nanosleep|d_clock_gettime|d_clock_getres|d_clock|d_clock_nanosleep)$/) { + $macro =~ s/^d_(.+)/TIME_HIRES_\U$1/; + } else { + $macro =~ s/^d_(.+)/HAS_\U$1/; + } push @names, {name => $_, macro => $macro, value => 1, default => ["IV", "0"]}; } @@ -427,7 +679,8 @@ sub doConstants { NAMES => \@names, ); } else { - foreach my $file ('const-c.inc', 'const-xs.inc') { + 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: $!"; @@ -441,20 +694,34 @@ sub doConstants { 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(); } doMakefile; doConstants; my $make = $Config{'make'} || "make"; - unless ($ENV{PERL_CORE}) { + unless (exists $ENV{PERL_CORE} && $ENV{PERL_CORE}) { print <