1#!/usr/bin/perl 2# 3# In general we trust %Config, but for nanosleep() this trust 4# may be misplaced (it may be linkable but not really functional). 5# Use $ENV{FORCE_NANOSLEEP_SCAN} to force rescanning whether there 6# really is hope. 7 8{ use 5.006; } 9 10use Config; 11use ExtUtils::MakeMaker; 12use strict; 13 14my $VERBOSE = $ENV{VERBOSE}; 15my $DEFINE; 16my $LIBS = []; 17my $XSOPT = ''; 18my $SYSCALL_H; 19 20our $self; # Used in 'sourcing' the hints. 21 22# TBD: Can we just use $Config(exe_ext) here instead of this complex 23# expression? 24my $ld_exeext = ($^O eq 'cygwin' || 25 $^O eq 'os2' && $Config{ldflags} =~ /-Zexe\b/) ? '.exe' : 26 (($^O eq 'vos') ? $Config{exe_ext} : ''); 27 28unless($ENV{PERL_CORE}) { 29 $ENV{PERL_CORE} = 1 if grep { $_ eq 'PERL_CORE=1' } @ARGV; 30} 31 32# Perls 5.002 and 5.003 did not have File::Spec, fake what we need. 33 34sub my_dirsep { 35 $^O eq 'VMS' ? '.' : 36 $^O =~ /mswin32|netware|djgpp/i ? '\\' : 37 $^O eq 'MacOS' ? ':' 38 : '/'; 39} 40 41sub my_catdir { 42 shift; 43 my $catdir = join(my_dirsep, @_); 44 $^O eq 'VMS' ? "[$catdir]" : $catdir; 45} 46 47sub my_catfile { 48 shift; 49 return join(my_dirsep, @_) unless $^O eq 'VMS'; 50 my $file = pop; 51 return my_catdir (undef, @_) . $file; 52} 53 54sub my_updir { 55 shift; 56 $^O eq 'VMS' ? "-" : ".."; 57} 58 59BEGIN { 60 eval { require File::Spec }; 61 if ($@) { 62 *File::Spec::catdir = \&my_catdir; 63 *File::Spec::updir = \&my_updir; 64 *File::Spec::catfile = \&my_catfile; 65 } 66} 67 68# Avoid 'used only once' warnings. 69my $nop1 = *File::Spec::catdir; 70my $nop2 = *File::Spec::updir; 71my $nop3 = *File::Spec::catfile; 72 73# if you have 5.004_03 (and some slightly older versions?), xsubpp 74# tries to generate line numbers in the C code generated from the .xs. 75# unfortunately, it is a little buggy around #ifdef'd code. 76# my choice is leave it in and have people with old perls complain 77# about the "Usage" bug, or leave it out and be unable to compile myself 78# without changing it, and then I'd always forget to change it before a 79# release. Sorry, Edward :) 80 81sub try_compile_and_link { 82 my ($c, %args) = @_; 83 84 my ($ok) = 0; 85 my ($tmp) = "tmp$$"; 86 local(*TMPC); 87 88 my $obj_ext = $Config{obj_ext} || ".o"; 89 unlink("$tmp.c", "$tmp$obj_ext"); 90 91 if (open(TMPC, '>', "$tmp.c")) { 92 print TMPC $c; 93 close(TMPC); 94 95 my $cccmd = $args{cccmd}; 96 97 my $errornull; 98 99 my $COREincdir; 100 101 if ($ENV{PERL_CORE}) { 102 my $updir = File::Spec->updir; 103 $COREincdir = File::Spec->catdir(($updir) x 2); 104 } else { 105 $COREincdir = File::Spec->catdir($Config{'archlibexp'}, 'CORE'); 106 } 107 108 if ($ENV{PERL_CORE}) { 109 unless (-f File::Spec->catfile($COREincdir, "EXTERN.h")) { 110 die <<__EOD__; 111Your environment variable PERL_CORE is '$ENV{PERL_CORE}' but there 112is no EXTERN.h in $COREincdir. 113Cannot continue, aborting. 114__EOD__ 115 } 116 } 117 118 my $ccflags = $Config{'ccflags'} . ' ' . "-I$COREincdir" 119 . ' -DPERL_NO_INLINE_FUNCTIONS'; 120 121 if ($^O eq 'VMS') { 122 $cccmd = "$Config{'cc'} /include=($COREincdir) $tmp.c"; 123 } 124 125 if ($args{silent} || !$VERBOSE) { 126 $errornull = "2>/dev/null" unless defined $errornull; 127 } else { 128 $errornull = ''; 129 } 130 131 $cccmd = "$Config{'cc'} -o $tmp $ccflags $tmp.c @$LIBS $errornull" 132 unless defined $cccmd; 133 134 if ($^O eq 'VMS') { 135 open( CMDFILE, '>', "$tmp.com" ); 136 print CMDFILE "\$ SET MESSAGE/NOFACILITY/NOSEVERITY/NOIDENT/NOTEXT\n"; 137 print CMDFILE "\$ $cccmd\n"; 138 print CMDFILE "\$ IF \$SEVERITY .NE. 1 THEN EXIT 44\n"; # escalate 139 close CMDFILE; 140 system("\@ $tmp.com"); 141 $ok = $?==0; 142 for ("$tmp.c", "$tmp$obj_ext", "$tmp.com", "$tmp$Config{exe_ext}") { 143 1 while unlink $_; 144 } 145 } 146 else 147 { 148 my $tmp_exe = "$tmp$ld_exeext"; 149 printf "cccmd = $cccmd\n" if $VERBOSE; 150 my $res = system($cccmd); 151 $ok = defined($res) && $res == 0 && -s $tmp_exe && -x _; 152 153 if ( $ok && exists $args{run} && $args{run} && !$ENV{TIME_HIRES_DONT_RUN_PROBES} ) { 154 my $tmp_exe = 155 File::Spec->catfile(File::Spec->curdir, $tmp_exe); 156 my @run = $tmp_exe; 157 unshift @run, $Config{run} if $Config{run} && -e $Config{run}; 158 printf "Running $tmp_exe..." if $VERBOSE; 159 if (system(@run) == 0) { 160 $ok = 1; 161 } else { 162 $ok = 0; 163 my $errno = $? >> 8; 164 local $! = $errno; 165 printf <<EOF; 166 167*** The test run of '$tmp_exe' failed: status $? 168*** (the status means: errno = $errno or '$!') 169*** DO NOT PANIC: this just means that *some* functionality will be missing. 170EOF 171 } 172 } 173 unlink("$tmp.c", $tmp_exe); 174 } 175 } 176 177 return $ok; 178} 179 180my $TIME_HEADERS = <<EOH; 181#include "EXTERN.h" 182#include "perl.h" 183#include "XSUB.h" 184#ifdef I_SYS_TYPES 185# include <sys/types.h> 186#endif 187#ifdef I_SYS_TIME 188# include <sys/time.h> 189#endif 190#ifdef I_SYS_SELECT 191# include <sys/select.h> /* struct timeval might be hidden in here */ 192#endif 193EOH 194 195sub has_gettimeofday { 196 # confusing but true (if condition true ==> -DHAS_GETTIMEOFDAY already) 197 return 0 if $Config{d_gettimeod}; 198 return 1 if try_compile_and_link(<<EOM); 199$TIME_HEADERS 200static int foo() 201{ 202 struct timeval tv; 203 gettimeofday(&tv, 0); 204} 205int main(int argc, char** argv) 206{ 207 foo(); 208} 209EOM 210 return 0; 211} 212 213sub has_x { 214 my ($x, %args) = @_; 215 216 return 1 if 217 try_compile_and_link(<<EOM, %args); 218#include "EXTERN.h" 219#include "perl.h" 220#include "XSUB.h" 221 222#ifdef I_UNISTD 223# include <unistd.h> 224#endif 225 226#ifdef I_SYS_TYPES 227# include <sys/types.h> 228#endif 229 230#ifdef I_SYS_TIME 231# include <sys/time.h> 232#endif 233 234int main(int argc, char** argv) 235{ 236 $x; 237} 238EOM 239 return 0; 240} 241 242sub has_nanosleep { 243 print "testing... "; 244 return 1 if 245 try_compile_and_link(<<EOM, run => 1); 246#include <time.h> 247#include <sys/time.h> 248#include <stdio.h> 249#include <stdlib.h> 250#include <errno.h> 251 252/* int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); */ 253 254int main(int argc, char** argv) { 255 struct timespec ts1, ts2; 256 int ret; 257 ts1.tv_sec = 0; 258 ts1.tv_nsec = 750000000; 259 ts2.tv_sec = 0; 260 ts2.tv_nsec = 0; 261 errno = 0; 262 ret = nanosleep(&ts1, &ts2); /* E.g. in AIX nanosleep() fails and sets errno to ENOSYS. */ 263 ret == 0 ? exit(0) : exit(errno ? errno : -1); 264} 265EOM 266} 267 268sub has_include { 269 my ($inc) = @_; 270 return 1 if 271 try_compile_and_link(<<EOM); 272#include "EXTERN.h" 273#include "perl.h" 274#include "XSUB.h" 275 276#include <$inc> 277int main(int argc, char** argv) 278{ 279 return 0; 280} 281EOM 282 return 0; 283} 284 285sub has_clock_xxx_syscall { 286 my $x = shift; 287 return 0 unless defined $SYSCALL_H; 288 return 1 if 289 try_compile_and_link(<<EOM, run => 1); 290#include "EXTERN.h" 291#include "perl.h" 292#include "XSUB.h" 293#include <time.h> 294#include <$SYSCALL_H> 295int main(int argc, char** argv) 296{ 297 struct timespec ts; 298 /* Many Linuxes get ENOSYS even though the syscall exists. */ 299 /* All implementations are supposed to support CLOCK_REALTIME. */ 300 int ret = syscall(SYS_clock_$x, CLOCK_REALTIME, &ts); 301 ret == 0 ? exit(0) : exit(errno ? errno : -1); 302} 303EOM 304} 305 306sub has_clock_xxx { 307 my $xxx = shift; 308 return 1 if 309 try_compile_and_link(<<EOM, run => 1); 310#include "EXTERN.h" 311#include "perl.h" 312#include "XSUB.h" 313#include <time.h> 314int main(int argc, char** argv) 315{ 316 struct timespec ts; 317 int ret = clock_$xxx(CLOCK_REALTIME, &ts); /* Many Linuxes get ENOSYS. */ 318 /* All implementations are supposed to support CLOCK_REALTIME. */ 319 ret == 0 ? exit(0) : exit(errno ? errno : -1); 320} 321EOM 322} 323 324sub has_clock { 325 return 1 if 326 try_compile_and_link(<<EOM, run => 1); 327#include "EXTERN.h" 328#include "perl.h" 329#include "XSUB.h" 330#include <time.h> 331int main(int argc, char** argv) 332{ 333 clock_t tictoc; 334 clock_t ret = clock(); 335 ret == (clock_t)-1 ? exit(errno ? errno : -1) : exit(0); 336} 337EOM 338} 339 340sub has_clock_nanosleep { 341 return 1 if 342 try_compile_and_link(<<EOM, run => 1); 343#include "EXTERN.h" 344#include "perl.h" 345#include "XSUB.h" 346#include <time.h> 347int main(int argc, char** argv) 348{ 349 int ret; 350 struct timespec ts1; 351 struct timespec ts2; 352 ts1.tv_sec = 0; 353 ts1.tv_nsec = 750000000;; 354 /* All implementations are supposed to support CLOCK_REALTIME. */ 355 ret = clock_nanosleep(CLOCK_REALTIME, 0, &ts1, &ts2); 356 ret == 0 ? exit(0) : exit(errno ? errno : -1); 357} 358EOM 359} 360 361sub has_futimens { 362 return 1 if 363 try_compile_and_link(<<EOM); 364#include "EXTERN.h" 365#include "perl.h" 366#include "XSUB.h" 367#include <sys/stat.h> 368int main(int argc, char** argv) 369{ 370 int ret1, ret2; 371 struct timespec ts1[2], ts2[2]; 372 ret1 = futimens(0, ts1); 373 char buf[1]; 374 read(0, buf, 0); /* Assuming reading nothing updates atime (the [0]) */ 375 ret2 = futimens(0, ts2); 376 ret1 == 0 && ret2 == 0 && (ts1[0].tv_nsec != 0 || ts2[0].tv_nsec != 0) ? 377 exit(0) : exit(errno ? errno : -1); 378} 379EOM 380} 381 382sub has_utimensat{ 383 return 1 if 384 try_compile_and_link(<<EOM); 385#include "EXTERN.h" 386#include "perl.h" 387#include "XSUB.h" 388#include <sys/stat.h> 389#include <fcntl.h> 390int main(int argc, char** argv) 391{ 392 int ret1, ret2; 393 struct timespec ts1[2], ts2[2]; 394 /* We make the brave but probably foolish assumption that systems 395 * modern enough to have utimensat also have the /dev/stdin. */ 396 ret1 = utimensat(AT_FDCWD, "/dev/stdin", ts1, 0); 397 char buf[1]; 398 read(0, buf, 0); /* Assuming reading nothing updates atime (the [0]) */ 399 ret2 = utimensat(AT_FDCWD, "/dev/stdin", ts2, 0); 400 ret1 == 0 && ret2 == 0 && (ts1[0].tv_nsec != 0 || ts2[0].tv_nsec != 0) ? 401 exit(0) : exit(errno ? errno : -1); 402} 403EOM 404} 405 406sub has_clockid_t{ 407 return 1 if 408 try_compile_and_link(<<EOM); 409#include "EXTERN.h" 410#include "perl.h" 411#include "XSUB.h" 412#include <time.h> 413int main(int argc, char** argv) 414{ 415 clockid_t id = CLOCK_REALTIME; 416 exit(id == CLOCK_REALTIME ? 1 : 0); 417} 418EOM 419} 420 421sub DEFINE { 422 my ($def, $val) = @_; 423 my $define = defined $val ? "$def=$val" : $def ; 424 unless ($DEFINE =~ /(?:^| )-D\Q$define\E(?: |$)/) { 425 $DEFINE .= " -D$define"; 426 } 427} 428 429sub init { 430 my $hints = File::Spec->catfile("hints", "$^O.pl"); 431 if (-f $hints) { 432 print "Using hints $hints...\n"; 433 local $self; 434 do "./$hints"; 435 if (exists $self->{LIBS}) { 436 $LIBS = $self->{LIBS}; 437 print "Extra libraries: @$LIBS...\n"; 438 } 439 } 440 441 $DEFINE = ''; 442 443 if ($Config{d_syscall}) { 444 print "Have syscall()... looking for syscall.h... "; 445 if (has_include('syscall.h')) { 446 $SYSCALL_H = 'syscall.h'; 447 } elsif (has_include('sys/syscall.h')) { 448 $SYSCALL_H = 'sys/syscall.h'; 449 } 450 } else { 451 print "No syscall()...\n"; 452 } 453 454 if ($Config{d_syscall}) { 455 if (defined $SYSCALL_H) { 456 print "found <$SYSCALL_H>.\n"; 457 } else { 458 print "NOT found.\n"; 459 } 460 } 461 462 print "Looking for gettimeofday()... "; 463 my $has_gettimeofday; 464 if (exists $Config{d_gettimeod}) { 465 $has_gettimeofday++ if $Config{d_gettimeod}; 466 } elsif (has_gettimeofday()) { 467 $DEFINE .= ' -DHAS_GETTIMEOFDAY'; 468 $has_gettimeofday++; 469 } 470 471 if ($has_gettimeofday) { 472 print "found.\n"; 473 } else { 474 die <<EOD 475Your operating system does not seem to have the gettimeofday() function. 476(or, at least, I cannot find it) 477 478There is no way Time::HiRes is going to work. 479 480I am awfully sorry but I cannot go further. 481 482Aborting configuration. 483 484EOD 485 } 486 487 print "Looking for setitimer()... "; 488 my $has_setitimer; 489 if (exists $Config{d_setitimer}) { 490 $has_setitimer++ if $Config{d_setitimer}; 491 } elsif (has_x("setitimer(ITIMER_REAL, 0, 0)")) { 492 $has_setitimer++; 493 $DEFINE .= ' -DHAS_SETITIMER'; 494 } 495 496 if ($has_setitimer) { 497 print "found.\n"; 498 } else { 499 print "NOT found.\n"; 500 } 501 502 print "Looking for getitimer()... "; 503 my $has_getitimer; 504 if (exists $Config{'d_getitimer'}) { 505 $has_getitimer++ if $Config{'d_getitimer'}; 506 } elsif (has_x("getitimer(ITIMER_REAL, 0)")) { 507 $has_getitimer++; 508 $DEFINE .= ' -DHAS_GETITIMER'; 509 } 510 511 if ($has_getitimer) { 512 print "found.\n"; 513 } else { 514 print "NOT found.\n"; 515 } 516 517 if ($has_setitimer && $has_getitimer) { 518 print "You have interval timers (both setitimer and getitimer).\n"; 519 } else { 520 print "You do NOT have interval timers.\n"; 521 } 522 523 print "Looking for ualarm()... "; 524 my $has_ualarm; 525 if (exists $Config{d_ualarm}) { 526 $has_ualarm++ if $Config{d_ualarm}; 527 } elsif (has_x ("ualarm (0, 0)")) { 528 $has_ualarm++; 529 $DEFINE .= ' -DHAS_UALARM'; 530 } 531 532 if ($has_ualarm) { 533 print "found.\n"; 534 } else { 535 print "NOT found.\n"; 536 if ($has_setitimer) { 537 print "But you have setitimer().\n"; 538 print "We can make a Time::HiRes::ualarm().\n"; 539 } 540 } 541 542 print "Looking for usleep()... "; 543 my $has_usleep; 544 if (exists $Config{d_usleep}) { 545 $has_usleep++ if $Config{d_usleep}; 546 } elsif (has_x ("usleep (0)")) { 547 $has_usleep++; 548 $DEFINE .= ' -DHAS_USLEEP'; 549 } 550 551 if ($has_usleep) { 552 print "found.\n"; 553 } else { 554 print "NOT found.\n"; 555 print "Let's see if you have select()... "; 556 if ($Config{'d_select'}) { 557 print "found.\n"; 558 print "We can make a Time::HiRes::usleep().\n"; 559 } else { 560 print "NOT found.\n"; 561 print "You won't have a Time::HiRes::usleep().\n"; 562 } 563 } 564 565 print "Looking for nanosleep()... "; 566 my $has_nanosleep; 567 if ($ENV{FORCE_NANOSLEEP_SCAN}) { 568 print "forced scan... "; 569 if (has_nanosleep()) { 570 $has_nanosleep++; 571 $DEFINE .= ' -DTIME_HIRES_NANOSLEEP'; 572 } 573 } 574 elsif (exists $Config{d_nanosleep}) { 575 print "believing \$Config{d_nanosleep}... "; 576 if ($Config{d_nanosleep}) { 577 $has_nanosleep++; 578 $DEFINE .= ' -DTIME_HIRES_NANOSLEEP'; 579 } 580 } elsif ($^O =~ /^(mpeix)$/) { 581 # MPE/iX falsely finds nanosleep from its libc equivalent. 582 print "skipping because in $^O... "; 583 } else { 584 if (has_nanosleep()) { 585 $has_nanosleep++; 586 $DEFINE .= ' -DTIME_HIRES_NANOSLEEP'; 587 } 588 } 589 590 if ($has_nanosleep) { 591 print "found.\n"; 592 print "You can mix subsecond sleeps with signals, if you want to.\n"; 593 print "(It's still not portable, though.)\n"; 594 } else { 595 print "NOT found.\n"; 596 my $nt = ($^O eq 'os2' ? '' : 'not'); 597 print "You can$nt mix subsecond sleeps with signals.\n"; 598 print "(It would not be portable anyway.)\n"; 599 } 600 601 print "Looking for clockid_t... "; 602 my $has_clockid_t; 603 if (has_clockid_t()) { 604 print "found.\n"; 605 $has_clockid_t++; 606 $DEFINE .= ' -DTIME_HIRES_CLOCKID_T'; 607 } else { 608 print "NOT found, will use int.\n"; 609 } 610 611 print "Looking for clock_gettime()... "; 612 my $has_clock_gettime; 613 my $has_clock_gettime_emulation; 614 if (exists $Config{d_clock_gettime}) { 615 $has_clock_gettime++ if $Config{d_clock_gettime}; # Unlikely... 616 } elsif (has_clock_xxx('gettime')) { 617 $has_clock_gettime++; 618 $DEFINE .= ' -DTIME_HIRES_CLOCK_GETTIME'; 619 } elsif (defined $SYSCALL_H && has_clock_xxx_syscall('gettime')) { 620 $has_clock_gettime++; 621 $DEFINE .= ' -DTIME_HIRES_CLOCK_GETTIME -DTIME_HIRES_CLOCK_GETTIME_SYSCALL'; 622 } elsif ($^O eq 'darwin') { 623 $has_clock_gettime_emulation++; 624 $has_clock_gettime++; 625 $DEFINE .= ' -DTIME_HIRES_CLOCK_GETTIME -DTIME_HIRES_CLOCK_GETTIME_EMULATION'; 626 } 627 628 if ($has_clock_gettime) { 629 if ($DEFINE =~ /-DTIME_HIRES_CLOCK_GETTIME_SYSCALL/) { 630 print "found (via syscall).\n"; 631 } elsif ($has_clock_gettime_emulation) { 632 print "found (via emulation).\n"; 633 } else { 634 print "found.\n"; 635 } 636 } else { 637 print "NOT found.\n"; 638 } 639 640 print "Looking for clock_getres()... "; 641 my $has_clock_getres; 642 my $has_clock_getres_emulation; 643 if (exists $Config{d_clock_getres}) { 644 $has_clock_getres++ if $Config{d_clock_getres}; # Unlikely... 645 } elsif (has_clock_xxx('getres')) { 646 $has_clock_getres++; 647 $DEFINE .= ' -DTIME_HIRES_CLOCK_GETRES'; 648 } elsif (defined $SYSCALL_H && has_clock_xxx_syscall('getres')) { 649 $has_clock_getres++; 650 $DEFINE .= ' -DTIME_HIRES_CLOCK_GETRES -DTIME_HIRES_CLOCK_GETRES_SYSCALL'; 651 } elsif ($^O eq 'darwin') { 652 $has_clock_getres_emulation++; 653 $has_clock_getres++; 654 $DEFINE .= ' -DTIME_HIRES_CLOCK_GETRES -DTIME_HIRES_CLOCK_GETRES_EMULATION'; 655 } 656 657 if ($has_clock_getres) { 658 if ($DEFINE =~ /-DTIME_HIRES_CLOCK_GETRES_SYSCALL/) { 659 print "found (via syscall).\n"; 660 } elsif ($has_clock_getres_emulation) { 661 print "found (via emulation).\n"; 662 } else { 663 print "found.\n"; 664 } 665 } else { 666 print "NOT found.\n"; 667 } 668 669 print "Looking for clock_nanosleep()... "; 670 my $has_clock_nanosleep; 671 my $has_clock_nanosleep_emulation; 672 if (exists $Config{d_clock_nanosleep}) { 673 $has_clock_nanosleep++ if $Config{d_clock_nanosleep}; # Unlikely... 674 } elsif (has_clock_nanosleep()) { 675 $has_clock_nanosleep++; 676 $DEFINE .= ' -DTIME_HIRES_CLOCK_NANOSLEEP'; 677 } elsif ($^O eq 'darwin') { 678 $has_clock_nanosleep++; 679 $has_clock_nanosleep_emulation++; 680 $DEFINE .= ' -DTIME_HIRES_CLOCK_NANOSLEEP -DTIME_HIRES_CLOCK_NANOSLEEP_EMULATION'; 681 } 682 683 if ($has_clock_nanosleep) { 684 if ($has_clock_nanosleep_emulation) { 685 print "found (via emulation).\n"; 686 } else { 687 print "found.\n"; 688 } 689 } else { 690 print "NOT found.\n"; 691 } 692 693 print "Looking for clock()... "; 694 my $has_clock; 695 if (exists $Config{d_clock}) { 696 $has_clock++ if $Config{d_clock}; # Unlikely... 697 } elsif (has_clock()) { 698 $has_clock++; 699 $DEFINE .= ' -DTIME_HIRES_CLOCK'; 700 } 701 702 if ($has_clock) { 703 print "found.\n"; 704 } else { 705 print "NOT found.\n"; 706 } 707 708 print "Looking for working futimens()... "; 709 my $has_futimens; 710 if (has_futimens()) { 711 $has_futimens++; 712 $DEFINE .= ' -DHAS_FUTIMENS'; 713 } 714 715 if ($has_futimens) { 716 print "found.\n"; 717 } else { 718 print "NOT found.\n"; 719 } 720 721 print "Looking for working utimensat()... "; 722 my $has_utimensat; 723 if (has_utimensat()) { 724 $has_utimensat++; 725 $DEFINE .= ' -DHAS_UTIMENSAT'; 726 } 727 728 if ($has_utimensat) { 729 print "found.\n"; 730 } else { 731 print "NOT found.\n"; 732 } 733 734 my $has_hires_utime = ($has_futimens && $has_utimensat); 735 if ($has_hires_utime) { 736 $DEFINE .= ' -DTIME_HIRES_UTIME'; 737 print "You seem to have subsecond timestamp setting.\n"; 738 } else { 739 print "You do NOT seem to have subsecond timestamp setting.\n"; 740 } 741 742 print "Looking for stat() subsecond timestamps...\n"; 743 744 print "Trying struct stat st_atimespec.tv_nsec..."; 745 my $has_stat_st_xtimespec; 746 if (try_compile_and_link(<<EOM)) { 747$TIME_HEADERS 748#include <sys/stat.h> 749int main(int argc, char** argv) { 750 struct stat st; 751 st.st_atimespec.tv_nsec = 0; 752} 753EOM 754 $has_stat_st_xtimespec++; 755 DEFINE('TIME_HIRES_STAT_ST_XTIMESPEC'); # 1 756 } 757 758 if ($has_stat_st_xtimespec) { 759 print "found.\n"; 760 } else { 761 print "NOT found.\n"; 762 } 763 764 print "Trying struct stat st_atimensec..."; 765 my $has_stat_st_xtimensec; 766 if (try_compile_and_link(<<EOM)) { 767$TIME_HEADERS 768#include <sys/stat.h> 769int main(int argc, char** argv) { 770 struct stat st; 771 st.st_atimensec = 0; 772} 773EOM 774 $has_stat_st_xtimensec++; 775 DEFINE('TIME_HIRES_STAT_ST_XTIMENSEC'); # 2 776 } 777 778 if ($has_stat_st_xtimensec) { 779 print "found.\n"; 780 } else { 781 print "NOT found.\n"; 782 } 783 784 print "Trying struct stat st_atime_n..."; 785 my $has_stat_st_xtime_n; 786 if (try_compile_and_link(<<EOM)) { 787$TIME_HEADERS 788#include <sys/stat.h> 789int main(int argc, char** argv) { 790 struct stat st; 791 st.st_atime_n = 0; 792} 793EOM 794 $has_stat_st_xtime_n++; 795 DEFINE('TIME_HIRES_STAT_ST_XTIME_N'); # 3 796 } 797 798 if ($has_stat_st_xtime_n) { 799 print "found.\n"; 800 } else { 801 print "NOT found.\n"; 802 } 803 804 print "Trying struct stat st_atim.tv_nsec..."; 805 my $has_stat_st_xtim; 806 if (try_compile_and_link(<<EOM)) { 807$TIME_HEADERS 808#include <sys/stat.h> 809int main(int argc, char** argv) { 810 struct stat st; 811 st.st_atim.tv_nsec = 0; 812} 813EOM 814 $has_stat_st_xtim++; 815 DEFINE('TIME_HIRES_STAT_XTIM'); # 4 816 } 817 818 if ($has_stat_st_xtim) { 819 print "found.\n"; 820 } else { 821 print "NOT found.\n"; 822 } 823 824 print "Trying struct stat st_uatime..."; 825 my $has_stat_st_uxtime; 826 if (try_compile_and_link(<<EOM)) { 827$TIME_HEADERS 828#include <sys/stat.h> 829int main(int argc, char** argv) { 830 struct stat st; 831 st.st_uatime = 0; 832} 833EOM 834 $has_stat_st_uxtime++; 835 DEFINE('TIME_HIRES_STAT_ST_UXTIME'); # 5 836 } 837 838 if ($has_stat_st_uxtime) { 839 print "found.\n"; 840 } else { 841 print "NOT found.\n"; 842 } 843 844 # See HiRes.xs hrstatns() 845 if ($has_stat_st_xtimespec) { 846 DEFINE('TIME_HIRES_STAT', 1); 847 } elsif ($has_stat_st_xtimensec) { 848 DEFINE('TIME_HIRES_STAT', 2); 849 } elsif ($has_stat_st_xtime_n) { 850 DEFINE('TIME_HIRES_STAT', 3); 851 } elsif ($has_stat_st_xtim) { 852 DEFINE('TIME_HIRES_STAT', 4); 853 } elsif ($has_stat_st_uxtime) { 854 DEFINE('TIME_HIRES_STAT', 5); 855 } 856 857 my $has_hires_stat = ($DEFINE =~ /-DTIME_HIRES_STAT=(\d+)/) ? $1 : 0; 858 if ($has_hires_stat) { 859 print "You seem to have subsecond timestamp reading.\n"; 860 print "(Your struct stat has them, but the filesystems must help.)\n"; 861 unless ($has_hires_utime) { 862 print "However, you do NOT seem to have subsecond timestamp setting.\n"; 863 } 864 } else { 865 print "You do NOT seem to have subsecond timestamp reading.\n"; 866 } 867 868 my $has_w32api_windows_h; 869 870 if ($^O eq 'cygwin') { 871 print "Looking for <w32api/windows.h>... "; 872 if (has_include('w32api/windows.h')) { 873 $has_w32api_windows_h++; 874 DEFINE('HAS_W32API_WINDOWS_H'); 875 } 876 if ($has_w32api_windows_h) { 877 print "found.\n"; 878 } else { 879 print "NOT found.\n"; 880 } 881 } 882 883 if ($DEFINE) { 884 $DEFINE =~ s/^\s+//; 885 if (open(XDEFINE, '>', 'xdefine')) { 886 print XDEFINE $DEFINE, "\n"; 887 close(XDEFINE); 888 } 889 } 890} 891 892sub doMakefile { 893 my @makefileopts = (); 894 895 if ($] >= 5.005) { 896 push (@makefileopts, 897 'AUTHOR' => 'Jarkko Hietaniemi <jhi@iki.fi>', 898 'ABSTRACT_FROM' => 'HiRes.pm', 899 ); 900 DEFINE('ATLEASTFIVEOHOHFIVE'); 901 } 902 DEFINE('USE_PPPORT_H') unless $ENV{PERL_CORE}; 903 904 push (@makefileopts, 905 'NAME' => 'Time::HiRes', 906 'VERSION_FROM' => 'HiRes.pm', # finds $VERSION 907 'LIBS' => $LIBS, # e.g., '-lm' 908 'DEFINE' => $DEFINE, # e.g., '-DHAS_SOMETHING' 909 'XSOPT' => $XSOPT, 910 # Do not even think about 'INC' => '-I/usr/ucbinclude', 911 # Solaris will avenge. 912 'INC' => '', # e.g., '-I/usr/include/other' 913 'INSTALLDIRS' => ($] >= 5.008 && $] < 5.011 ? 'perl' : 'site'), 914 'PREREQ_PM' => { 915 'Carp' => 0, 916 'Config' => 0, 917 'Exporter' => 0, 918 'ExtUtils::MakeMaker' => 0, 919 'Test::More' => 0, 920 'XSLoader' => 0, 921 'strict' => 0, 922 }, 923 'dist' => { 924 'CI' => 'ci -l', 925 'COMPRESS' => 'gzip -9f', 926 'SUFFIX' => 'gz', 927 }, 928 clean => { FILES => "xdefine" }, 929 realclean => { FILES=> 'const-c.inc const-xs.inc' }, 930 ); 931 932 if ($^O eq "MSWin32" && !(grep { /\ALD[A-Z]*=/ } @ARGV)) { 933 my $libperl = $Config{libperl} || ""; 934 my $gccversion = $Config{gccversion} || ""; 935 if ($gccversion =~ /\A3\.4\.[0-9]+/ and $libperl =~ /\.lib\z/) { 936 # Avoid broken linkage with ActivePerl, by linking directly 937 # against the Perl DLL rather than the import library. 938 (my $llibperl = "-l$libperl") =~ s/\.lib\z//; 939 my $lddlflags = $Config{lddlflags} || ""; 940 my $ldflags = $Config{ldflags} || ""; 941 s/-L(?:".*?"|\S+)//g foreach $lddlflags, $ldflags; 942 my $libdirs = join ' ', 943 map { s/(?<!\\)((?:\\\\)*")/\\$1/g; qq[-L"$_"] } 944 @Config{qw/bin sitebin/}; 945 push @makefileopts, macro => { 946 LDDLFLAGS => "$lddlflags $libdirs $llibperl", 947 LDFLAGS => "$ldflags $libdirs $llibperl", 948 PERL_ARCHIVE => "", 949 }; 950 } 951 } 952 953 if ($ENV{PERL_CORE}) { 954 push @makefileopts, MAN3PODS => {}; 955 } 956 957 if ($ExtUtils::MakeMaker::VERSION >= 6.48) { 958 push @makefileopts, (MIN_PERL_VERSION => '5.006',); 959 } 960 961 if ($ExtUtils::MakeMaker::VERSION >= 6.31) { 962 push @makefileopts, (LICENSE => 'perl_5'); 963 } 964 965 WriteMakefile(@makefileopts); 966} 967 968sub doConstants { 969 if (eval {require ExtUtils::Constant; 1}) { 970 # More or less this same list is in HiRes.pm. Should unify. 971 my @names = qw( 972 CLOCKS_PER_SEC 973 CLOCK_BOOTTIME 974 CLOCK_HIGHRES 975 CLOCK_MONOTONIC 976 CLOCK_MONOTONIC_COARSE 977 CLOCK_MONOTONIC_FAST 978 CLOCK_MONOTONIC_PRECISE 979 CLOCK_MONOTONIC_RAW 980 CLOCK_PROF 981 CLOCK_PROCESS_CPUTIME_ID 982 CLOCK_REALTIME 983 CLOCK_REALTIME_COARSE 984 CLOCK_REALTIME_FAST 985 CLOCK_REALTIME_PRECISE 986 CLOCK_REALTIME_RAW 987 CLOCK_SECOND 988 CLOCK_SOFTTIME 989 CLOCK_THREAD_CPUTIME_ID 990 CLOCK_TIMEOFDAY 991 CLOCK_UPTIME 992 CLOCK_UPTIME_COARSE 993 CLOCK_UPTIME_FAST 994 CLOCK_UPTIME_PRECISE 995 CLOCK_UPTIME_RAW 996 CLOCK_VIRTUAL 997 ITIMER_PROF 998 ITIMER_REAL 999 ITIMER_REALPROF 1000 ITIMER_VIRTUAL 1001 TIMER_ABSTIME 1002 ); 1003 foreach (qw (d_usleep d_ualarm d_gettimeofday d_getitimer d_setitimer 1004 d_nanosleep d_clock_gettime d_clock_getres 1005 d_clock d_clock_nanosleep d_hires_stat 1006 d_futimens d_utimensat d_hires_utime)) { 1007 my $macro = $_; 1008 if ($macro =~ /^(d_nanosleep|d_clock)$/) { 1009 $macro =~ s/^d_(.+)/TIME_HIRES_\U$1/; 1010 } elsif ($macro =~ /^(d_hires_stat)$/) { 1011 my $d_hires_stat = $1 if ($DEFINE =~ /-DTIME_HIRES_STAT=(\d+)/); 1012 if (defined $d_hires_stat) { 1013 push @names, {name => $_, macro => "TIME_HIRES_STAT", value => $d_hires_stat, 1014 default => ["IV", "0"]}; 1015 next; 1016 } 1017 } elsif ($macro =~ /^(d_hires_utime)$/) { 1018 my $d_hires_utime = 1019 ($DEFINE =~ /-DHAS_FUTIMENS/ || 1020 $DEFINE =~ /-DHAS_UTIMENSAT/); 1021 push @names, {name => $_, macro => "TIME_HIRES_UTIME", value => $d_hires_utime, 1022 default => ["IV", "0"]}; 1023 next; 1024 } elsif ($macro =~ /^(d_clock_gettime|d_clock_getres|d_clock_nanosleep)$/) { 1025 $macro =~ s/^d_(.+)/TIME_HIRES_\U$1/; 1026 my $val = ($DEFINE =~ /-D$macro\b/) ? 1 : 0; 1027 push @names, {name => $_, macro => $macro, value => $val, 1028 default => ["IV", "0"]}; 1029 next; 1030 } else { 1031 $macro =~ s/^d_(.+)/HAS_\U$1/; 1032 } 1033 push @names, {name => $_, macro => $macro, value => 1, 1034 default => ["IV", "0"]}; 1035 } 1036 ExtUtils::Constant::WriteConstants( 1037 NAME => 'Time::HiRes', 1038 NAMES => \@names, 1039 ); 1040 } else { 1041 my $file; 1042 foreach $file ('const-c.inc', 'const-xs.inc') { 1043 my $fallback = File::Spec->catfile('fallback', $file); 1044 local $/; 1045 open IN, '<', $fallback or die "Can't open $fallback: $!"; 1046 open OUT, '>', $file or die "Can't open $file: $!"; 1047 print OUT <IN> or die $!; 1048 close OUT or die "Can't close $file: $!"; 1049 close IN or die "Can't close $fallback: $!"; 1050 } 1051 } 1052} 1053 1054sub main { 1055 if (-f "xdefine" && !(@ARGV && $ARGV[0] =~ /^--(?:configure|force)$/)) { 1056 print qq[$0: The "xdefine" exists, skipping the configure step.\n]; 1057 print qq[Use "$^X $0 --configure"\n]; 1058 print qq[or: "$^X $0 --force\n]; 1059 print qq[to force the configure step.\n]; 1060 } else { 1061 print "Configuring Time::HiRes...\n"; 1062 1 while unlink("define"); 1063 if ($^O =~ /Win32/i) { 1064 DEFINE('SELECT_IS_BROKEN'); 1065 $LIBS = []; 1066 print "System is $^O, skipping full configure...\n"; 1067 open(XDEFINE, '>', 'xdefine') or die "$0: Cannot create xdefine: $!\n"; 1068 close(XDEFINE); 1069 } else { 1070 init(); 1071 } 1072 doMakefile; 1073 doConstants; 1074 } 1075 my $make = $Config{'make'} || "make"; 1076 unless (exists $ENV{PERL_CORE} && $ENV{PERL_CORE}) { 1077 print <<EOM; 1078Now you may issue '$make'. Do not forget also '$make test'. 1079EOM 1080 if ($] == 5.008 && 1081 ((exists $ENV{LC_ALL} && $ENV{LC_ALL} =~ /utf-?8/i) || 1082 (exists $ENV{LC_CTYPE} && $ENV{LC_CTYPE} =~ /utf-?8/i) || 1083 (exists $ENV{LANG} && $ENV{LANG} =~ /utf-?8/i))) { 1084 print <<EOM; 1085 1086NOTE: if you get an error like this (the Makefile line number may vary): 1087Makefile:91: *** missing separator 1088then set the environment variable LC_ALL to "C" and retry 1089from scratch (re-run perl "Makefile.PL"). 1090(And consider upgrading your Perl to, say, at least Perl 5.8.8.) 1091(You got this message because you seem to have 1092 an UTF-8 locale active in your shell environment, this used 1093 to cause broken Makefiles to be created from Makefile.PLs) 1094EOM 1095 } 1096 } 1097} 1098 1099&main; 1100 1101# EOF 1102