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