This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Upgrade to Time-HiRes-1.9703
[perl5.git] / ext / Time / HiRes / Makefile.PL
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 require 5.002;
9
10 use Config;
11 use ExtUtils::MakeMaker;
12 use strict;
13
14 my $VERBOSE = $ENV{VERBOSE};
15 my $DEFINE;
16 my $LIBS = [];
17 my $XSOPT = '';
18 my $SYSCALL_H;
19
20 use vars qw($self); # Used in 'sourcing' the hints.
21
22 my $ld_exeext = ($^O eq 'cygwin' ||
23                  $^O eq 'os2' && $Config{ldflags} =~ /-Zexe\b/) ? '.exe' : '';
24
25 unless($ENV{PERL_CORE}) {
26     $ENV{PERL_CORE} = 1 if grep { $_ eq 'PERL_CORE=1' } @ARGV;
27 }
28
29 # Perls 5.002 and 5.003 did not have File::Spec, fake what we need.
30
31 sub my_dirsep {
32     $^O eq 'VMS' ? '.' :
33         $^O =~ /mswin32|netware|djgpp/i ? '\\' :
34             $^O eq 'MacOS' ? ':'
35                 : '/';
36 }
37
38 sub my_catdir {
39     shift;
40     my $catdir = join(my_dirsep, @_);
41     $^O eq 'VMS' ? "[$catdir]" : $catdir;
42 }
43
44 sub my_catfile {
45     shift;
46     return join(my_dirsep, @_) unless $^O eq 'VMS';
47     my $file = pop;
48     return my_catdir (undef, @_) . $file;
49 }
50
51 sub my_updir {
52     shift;
53     $^O eq 'VMS' ? "-" : "..";
54 }
55
56 BEGIN {
57     eval { require File::Spec };
58     if ($@) {
59         *File::Spec::catdir  = \&my_catdir;
60         *File::Spec::updir   = \&my_updir;
61         *File::Spec::catfile = \&my_catfile;
62     }
63 }
64
65 # Avoid 'used only once' warnings.
66 my $nop1 = *File::Spec::catdir;
67 my $nop2 = *File::Spec::updir;
68 my $nop3 = *File::Spec::catfile;
69
70 # if you have 5.004_03 (and some slightly older versions?), xsubpp
71 # tries to generate line numbers in the C code generated from the .xs.
72 # unfortunately, it is a little buggy around #ifdef'd code.
73 # my choice is leave it in and have people with old perls complain
74 # about the "Usage" bug, or leave it out and be unable to compile myself
75 # without changing it, and then I'd always forget to change it before a
76 # release. Sorry, Edward :)
77
78 sub try_compile_and_link {
79     my ($c, %args) = @_;
80
81     my ($ok) = 0;
82     my ($tmp) = "tmp$$";
83     local(*TMPC);
84
85     my $obj_ext = $Config{obj_ext} || ".o";
86     unlink("$tmp.c", "$tmp$obj_ext");
87
88     if (open(TMPC, ">$tmp.c")) {
89         print TMPC $c;
90         close(TMPC);
91
92         my $cccmd = $args{cccmd};
93
94         my $errornull;
95
96         my $COREincdir;
97
98         if ($ENV{PERL_CORE}) {
99             my $updir = File::Spec->updir;
100             $COREincdir = File::Spec->catdir(($updir) x 3);
101         } else {
102             $COREincdir = File::Spec->catdir($Config{'archlibexp'}, 'CORE');
103         }
104
105         if ($ENV{PERL_CORE}) {
106             unless (-f File::Spec->catfile($COREincdir, "EXTERN.h")) {
107                 die <<__EOD__;
108 Your environment variable PERL_CORE is '$ENV{PERL_CORE}' but there
109 is no EXTERN.h in $COREincdir.
110 Cannot continue, aborting.
111 __EOD__
112             }
113         }
114
115         my $ccflags = $Config{'ccflags'} . ' ' . "-I$COREincdir";
116
117         if ($^O eq 'VMS') {
118             if ($ENV{PERL_CORE}) {
119                 # Fragile if the extensions change hierarchy within
120                 # the Perl core but this should do for now.
121                 $cccmd = "$Config{'cc'} /include=([---]) $tmp.c";
122             } else {
123                 my $perl_core = $Config{'installarchlib'};
124                 $perl_core =~ s/\]$/.CORE]/;
125                 $cccmd = "$Config{'cc'} /include=(perl_root:[000000],$perl_core) $tmp.c";
126             }
127         }
128
129         if ($args{silent} || !$VERBOSE) {
130             $errornull = "2>/dev/null" unless defined $errornull;
131         } else {
132             $errornull = '';
133         }
134
135         $cccmd = "$Config{'cc'} -o $tmp $ccflags $tmp.c @$LIBS $errornull"
136             unless defined $cccmd;
137
138        if ($^O eq 'VMS') {
139             open( CMDFILE, ">$tmp.com" );
140             print CMDFILE "\$ SET MESSAGE/NOFACILITY/NOSEVERITY/NOIDENT/NOTEXT\n";
141             print CMDFILE "\$ $cccmd\n";
142             print CMDFILE "\$ IF \$SEVERITY .NE. 1 THEN EXIT 44\n"; # escalate
143             close CMDFILE;
144             system("\@ $tmp.com");
145             $ok = $?==0;
146             for ("$tmp.c", "$tmp$obj_ext", "$tmp.com", "$tmp$Config{exe_ext}") {
147                 1 while unlink $_;
148             }
149         }
150         else
151         {
152             my $tmp_exe = "$tmp$ld_exeext";
153             printf "cccmd = $cccmd\n" if $VERBOSE;
154             my $res = system($cccmd);
155             $ok = defined($res) && $res == 0 && -s $tmp_exe && -x _;
156
157             if ( $ok && exists $args{run} && $args{run}) {
158                 my $tmp_exe =
159                     File::Spec->catfile(File::Spec->curdir, $tmp_exe);
160                 printf "Running $tmp_exe..." if $VERBOSE;
161                 if (system($tmp_exe) == 0) {
162                     $ok = 1;
163                 } else {
164                     $ok = 0;
165                     my $errno = $? >> 8;
166                     local $! = $errno;
167                     printf <<EOF;
168
169 *** The test run of '$tmp_exe' failed: status $?
170 *** (the status means: errno = $errno or '$!')
171 *** DO NOT PANIC: this just means that *some* functionality will be missing.
172 EOF
173                 }
174             }
175             unlink("$tmp.c", $tmp_exe);
176         }
177     }
178
179     return $ok;
180 }
181
182 my $TIME_HEADERS = <<EOH;
183 #include "EXTERN.h"
184 #include "perl.h"
185 #include "XSUB.h"
186 #ifdef I_SYS_TYPES
187 #   include <sys/types.h>
188 #endif
189 #ifdef I_SYS_TIME
190 #   include <sys/time.h>
191 #endif
192 #ifdef I_SYS_SELECT
193 #   include <sys/select.h>      /* struct timeval might be hidden in here */
194 #endif
195 EOH
196
197 sub has_gettimeofday {
198     # confusing but true (if condition true ==> -DHAS_GETTIMEOFDAY already)
199     return 0 if $Config{d_gettimeod};
200     return 1 if try_compile_and_link(<<EOM);
201 $TIME_HEADERS
202 static int foo()
203 {
204     struct timeval tv;
205     gettimeofday(&tv, 0);
206 }
207 int main(int argc, char** argv)
208 {
209     foo();
210 }
211 EOM
212     return 0;
213 }
214
215 sub has_x {
216     my ($x, %args) = @_;
217
218     return 1 if
219     try_compile_and_link(<<EOM, %args);
220 #include "EXTERN.h"
221 #include "perl.h"
222 #include "XSUB.h"
223
224 #ifdef I_UNISTD
225 #   include <unistd.h>
226 #endif
227
228 #ifdef I_SYS_TYPES
229 #   include <sys/types.h>
230 #endif
231
232 #ifdef I_SYS_TIME
233 #   include <sys/time.h>
234 #endif
235
236 int main(int argc, char** argv)
237 {
238         $x;
239 }
240 EOM
241     return 0;
242 }
243
244 sub has_nanosleep {
245     print "testing... ";
246     return 1 if
247     try_compile_and_link(<<EOM, run => 1);
248 #include <time.h>
249 #include <sys/time.h>
250 #include <stdio.h>
251 #include <stdlib.h>
252 #include <errno.h>
253
254 /* int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); */
255
256 int main(int argc, char** argv) {
257     struct timespec ts1, ts2;
258     int ret;
259     ts1.tv_sec  = 0;
260     ts1.tv_nsec = 750000000;
261     ts2.tv_sec  = 0;
262     ts2.tv_nsec = 0;
263     errno = 0;
264     ret = nanosleep(&ts1, &ts2); /* E.g. in AIX nanosleep() fails and sets errno to ENOSYS. */
265     ret == 0 ? exit(0) : exit(errno ? errno : -1);
266 }
267 EOM
268 }
269
270 sub has_include {
271     my ($inc) = @_;
272     return 1 if
273     try_compile_and_link(<<EOM);
274 #include "EXTERN.h"
275 #include "perl.h"
276 #include "XSUB.h"
277
278 #include <$inc>
279 int main(int argc, char** argv)
280 {
281         return 0;
282 }
283 EOM
284     return 0;
285 }
286
287 sub has_clock_xxx_syscall {
288     my $x = shift;
289     return 0 unless defined $SYSCALL_H;
290     return 1 if
291     try_compile_and_link(<<EOM, run => 1);
292 #include "EXTERN.h"
293 #include "perl.h"
294 #include "XSUB.h"
295 #include <$SYSCALL_H>
296 int main(int argc, char** argv)
297 {
298     struct timespec ts;
299     /* Many Linuxes get ENOSYS even though the syscall exists. */
300     /* All implementations are supposed to support CLOCK_REALTIME. */
301     int ret = syscall(SYS_clock_$x, CLOCK_REALTIME, &ts);
302     ret == 0 ? exit(0) : exit(errno ? errno : -1);
303 }
304 EOM
305 }
306
307 sub has_clock_xxx {
308     my $xxx = shift;
309     return 1 if
310     try_compile_and_link(<<EOM, run => 1);
311 #include "EXTERN.h"
312 #include "perl.h"
313 #include "XSUB.h"
314 int 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 }
321 EOM
322 }
323
324 sub 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 int main(int argc, char** argv)
331 {
332     clock_t tictoc;
333     clock_t ret = clock();
334     ret == (clock_t)-1 ? exit(errno ? errno : -1) : exit(0);
335 }
336 EOM
337 }
338
339 sub has_clock_nanosleep {
340     return 1 if
341     try_compile_and_link(<<EOM, run => 1);
342 #include "EXTERN.h"
343 #include "perl.h"
344 #include "XSUB.h"
345 int main(int argc, char** argv)
346 {
347     int ret;
348     struct timerspec ts1;
349     struct timerspec ts2;
350     ts1.tv_sec  = 0;
351     ts1.tv_nsec = 750000000;;
352     ret = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts1, &ts2);
353     ret == 0 ? exit(0) : exit(errno ? errno : -1);
354 }
355 EOM
356 }
357
358 sub init {
359     my $hints = File::Spec->catfile("hints", "$^O.pl");
360     if (-f $hints) {
361         print "Using hints $hints...\n";
362         local $self;
363         do $hints;
364         if (exists $self->{LIBS}) {
365             $LIBS = $self->{LIBS};
366             print "Extra libraries: @$LIBS...\n";
367         }
368     }
369
370     $DEFINE = '';
371
372     if ($Config{d_syscall}) {
373         print "Have syscall()... looking for syscall.h... ";
374         if (has_include('syscall.h')) {
375             $SYSCALL_H = 'syscall.h';
376         } elsif (has_include('sys/syscall.h')) {
377             $SYSCALL_H = 'sys/syscall.h';
378         }
379     } else {
380         print "No syscall()...\n";
381     }
382
383     if ($Config{d_syscall}) {
384         if (defined $SYSCALL_H) {
385             print "found <$SYSCALL_H>.\n";
386         } else {
387             print "NOT found.\n";
388         }
389     }
390
391     print "Looking for gettimeofday()... ";
392     my $has_gettimeofday;
393     if (exists $Config{d_gettimeod}) {
394         $has_gettimeofday++ if $Config{d_gettimeod};
395     } elsif (has_gettimeofday()) {
396         $DEFINE .= ' -DHAS_GETTIMEOFDAY';
397         $has_gettimeofday++;
398     }
399
400     if ($has_gettimeofday) {
401         print "found.\n";
402     } else {
403         die <<EOD
404 Your operating system does not seem to have the gettimeofday() function.
405 (or, at least, I cannot find it)
406
407 There is no way Time::HiRes is going to work.
408
409 I am awfully sorry but I cannot go further.
410
411 Aborting configuration.
412
413 EOD
414     }
415
416     print "Looking for setitimer()... ";
417     my $has_setitimer;
418     if (exists $Config{d_setitimer}) {
419         $has_setitimer++ if $Config{d_setitimer};
420     } elsif (has_x("setitimer(ITIMER_REAL, 0, 0)")) {
421         $has_setitimer++;
422         $DEFINE .= ' -DHAS_SETITIMER';
423     }
424
425     if ($has_setitimer) {
426         print "found.\n";
427     } else {
428         print "NOT found.\n";
429     }
430
431     print "Looking for getitimer()... ";
432     my $has_getitimer;
433     if (exists $Config{'d_getitimer'}) {
434         $has_getitimer++ if $Config{'d_getitimer'};
435     } elsif (has_x("getitimer(ITIMER_REAL, 0)")) {
436         $has_getitimer++;
437         $DEFINE .= ' -DHAS_GETITIMER';
438     }
439
440     if ($has_getitimer) {
441         print "found.\n";
442     } else {
443         print "NOT found.\n";
444     }
445
446     if ($has_setitimer && $has_getitimer) {
447         print "You have interval timers (both setitimer and getitimer).\n";
448     } else {
449         print "You do not have interval timers.\n";
450     }
451
452     print "Looking for ualarm()... ";
453     my $has_ualarm;
454     if (exists $Config{d_ualarm}) {
455         $has_ualarm++ if $Config{d_ualarm};
456     } elsif (has_x ("ualarm (0, 0)")) {
457         $has_ualarm++;
458         $DEFINE .= ' -DHAS_UALARM';
459     }
460
461     if ($has_ualarm) {
462         print "found.\n";
463     } else {
464         print "NOT found.\n";
465         if ($has_setitimer) {
466             print "But you have setitimer().\n";
467             print "We can make a Time::HiRes::ualarm().\n";
468         }
469     }
470
471     print "Looking for usleep()... ";
472     my $has_usleep;
473     if (exists $Config{d_usleep}) {
474         $has_usleep++ if $Config{d_usleep};
475     } elsif (has_x ("usleep (0)")) {
476         $has_usleep++;
477         $DEFINE .= ' -DHAS_USLEEP';
478     }
479
480     if ($has_usleep) {
481         print "found.\n";
482     } else {
483         print "NOT found.\n";
484         print "Let's see if you have select()... ";
485         if ($Config{'d_select'}) {
486             print "found.\n";
487             print "We can make a Time::HiRes::usleep().\n";
488         } else {
489             print "NOT found.\n";
490             print "You won't have a Time::HiRes::usleep().\n";
491         }
492     }
493
494     print "Looking for nanosleep()... ";
495     my $has_nanosleep;
496     if ($ENV{FORCE_NANOSLEEP_SCAN}) {
497         print "forced scan... ";
498         if (has_nanosleep()) {
499             $has_nanosleep++;
500             $DEFINE .= ' -DTIME_HIRES_NANOSLEEP';
501         }
502     }
503     elsif (exists $Config{d_nanosleep}) {
504         print "believing \$Config{d_nanosleep}... ";
505         if ($Config{d_nanosleep}) {
506             $has_nanosleep++;
507             $DEFINE .= ' -DTIME_HIRES_NANOSLEEP';
508         }
509     } elsif ($^O =~ /^(mpeix)$/) {
510         # MPE/iX falsely finds nanosleep from its libc equivalent.
511         print "skipping because in $^O... ";
512     } else {
513         if (has_nanosleep()) {
514             $has_nanosleep++;
515             $DEFINE .= ' -DTIME_HIRES_NANOSLEEP';
516         }
517     }
518
519     if ($has_nanosleep) {
520         print "found.\n";
521         print "You can mix subsecond sleeps with signals, if you want to.\n";
522         print "(It's still not portable, though.)\n";
523     } else {
524         print "NOT found.\n";
525         my $nt = ($^O eq 'os2' ? '' : 'not');
526         print "You can$nt mix subsecond sleeps with signals.\n";
527         print "(It would not be portable anyway.)\n";
528     }
529
530     print "Looking for clock_gettime()... ";
531     my $has_clock_gettime;
532     if (exists $Config{d_clock_gettime}) {
533         $has_clock_gettime++ if $Config{d_clock_gettime}; # Unlikely...
534     } elsif (has_clock_xxx('gettime')) {
535         $has_clock_gettime++;
536         $DEFINE .= ' -DTIME_HIRES_CLOCK_GETTIME';
537     } elsif (defined $SYSCALL_H && has_clock_xxx_syscall('gettime')) {
538         $has_clock_gettime++;
539         $DEFINE .= ' -DTIME_HIRES_CLOCK_GETTIME -DTIME_HIRES_CLOCK_GETTIME_SYSCALL';
540     }
541
542     if ($has_clock_gettime) {
543         if ($DEFINE =~ /-DTIME_HIRES_CLOCK_GETTIME_SYSCALL/) {
544             print "found (via syscall).\n";
545         } else {
546             print "found.\n";
547         }
548     } else {
549         print "NOT found.\n";
550     }
551
552     print "Looking for clock_getres()... ";
553     my $has_clock_getres;
554     if (exists $Config{d_clock_getres}) {
555         $has_clock_getres++ if $Config{d_clock_getres}; # Unlikely...
556     } elsif (has_clock_xxx('getres')) {
557         $has_clock_getres++;
558         $DEFINE .= ' -DTIME_HIRES_CLOCK_GETRES';
559     } elsif (defined $SYSCALL_H && has_clock_xxx_syscall('getres')) {
560         $has_clock_getres++;
561         $DEFINE .= ' -DTIME_HIRES_CLOCK_GETRES -DTIME_HIRES_CLOCK_GETRES_SYSCALL';
562     }
563
564     if ($has_clock_getres) {
565         if ($DEFINE =~ /-DTIME_HIRES_CLOCK_GETRES_SYSCALL/) {
566             print "found (via syscall).\n";
567         } else {
568             print "found.\n";
569         }
570     } else {
571         print "NOT found.\n";
572     }
573
574     print "Looking for clock_nanosleep()... ";
575     my $has_clock_nanosleep;
576     if (exists $Config{d_clock_nanosleep}) {
577         $has_clock_nanosleep++ if $Config{d_clock_nanosleep}; # Unlikely...
578     } elsif (has_clock_nanosleep()) {
579         $has_clock_nanosleep++;
580         $DEFINE .= ' -DTIME_HIRES_CLOCK_NANOSLEEP';
581     }
582
583     if ($has_clock_nanosleep) {
584         print "found.\n";
585     } else {
586         print "NOT found.\n";
587     }
588
589     print "Looking for clock()... ";
590     my $has_clock;
591     if (exists $Config{d_clock}) {
592         $has_clock++ if $Config{d_clock}; # Unlikely...
593     } elsif (has_clock()) {
594         $has_clock++;
595         $DEFINE .= ' -DTIME_HIRES_CLOCK';
596     }
597
598     if ($has_clock) {
599         print "found.\n";
600     } else {
601         print "NOT found.\n";
602     }
603
604     print "Looking for stat() subsecond timestamps...\n";
605
606     print "Trying struct stat st_atimespec.tv_nsec...";
607     my $has_stat_st_xtimespec;
608     if (try_compile_and_link(<<EOM)) {
609 $TIME_HEADERS
610 #include <sys/stat.h>
611 int main(int argc, char** argv) {
612     struct stat st;
613     st.st_atimespec.tv_nsec = 0;
614 }
615 EOM
616       $has_stat_st_xtimespec++;
617       $DEFINE .= ' -DTIME_HIRES_STAT=1';
618     }
619
620     if ($has_stat_st_xtimespec) {
621         print "found.\n";
622     } else {
623         print "NOT found.\n";
624     }
625
626     print "Trying struct stat st_atimensec...";
627     my $has_stat_st_xtimensec;
628     if (try_compile_and_link(<<EOM)) {
629 $TIME_HEADERS
630 #include <sys/stat.h>
631 int main(int argc, char** argv) {
632     struct stat st;
633     st.st_atimensec = 0;
634 }
635 EOM
636       $has_stat_st_xtimensec++;
637       $DEFINE .= ' -DTIME_HIRES_STAT=2';
638     }
639
640     if ($has_stat_st_xtimensec) {
641         print "found.\n";
642     } else {
643         print "NOT found.\n";
644     }
645
646     print "Trying struct stat st_atime_n...";
647     my $has_stat_st_xtime_n;
648     if (try_compile_and_link(<<EOM)) {
649 $TIME_HEADERS
650 #include <sys/stat.h>
651 int main(int argc, char** argv) {
652     struct stat st;
653     st.st_atime_n = 0;
654 }
655 EOM
656       $has_stat_st_xtime_n++;
657       $DEFINE .= ' -DTIME_HIRES_STAT=3';
658     }
659
660     if ($has_stat_st_xtime_n) {
661         print "found.\n";
662     } else {
663         print "NOT found.\n";
664     }
665
666     print "Trying struct stat st_atim.tv_nsec...";
667     my $has_stat_st_xtim;
668     if (try_compile_and_link(<<EOM)) {
669 $TIME_HEADERS
670 #include <sys/stat.h>
671 int main(int argc, char** argv) {
672     struct stat st;
673     st.st_atim.tv_nsec = 0;
674 }
675 EOM
676       $has_stat_st_xtim++;
677       $DEFINE .= ' -DTIME_HIRES_STAT=4';
678     }
679
680     if ($has_stat_st_xtim) {
681         print "found.\n";
682     } else {
683         print "NOT found.\n";
684     }
685
686     print "Trying struct stat st_uatime...";
687     my $has_stat_st_uxtime;
688     if (try_compile_and_link(<<EOM)) {
689 $TIME_HEADERS
690 #include <sys/stat.h>
691 int main(int argc, char** argv) {
692     struct stat st;
693     st.st_uatime = 0;
694 }
695 EOM
696       $has_stat_st_uxtime++;
697       $DEFINE .= ' -DTIME_HIRES_STAT=5';
698     }
699
700     if ($has_stat_st_uxtime) {
701         print "found.\n";
702     } else {
703         print "NOT found.\n";
704     }
705
706    if ($DEFINE =~ /-DTIME_HIRES_STAT=\d+/) {
707     print "You seem to have stat() subsecond timestamps.\n";
708     print "(Your struct stat has them, but the filesystems must help.)\n";
709    } else {
710     print "You do not seem to have stat subsecond timestamps.\n";
711    }
712
713     my $has_w32api_windows_h;
714
715     if ($^O eq 'cygwin') {
716         print "Looking for <w32api/windows.h>... ";
717         if (has_include('w32api/windows.h')) {
718             $has_w32api_windows_h++;
719             $DEFINE .= ' -DHAS_W32API_WINDOWS_H';
720         }
721         if ($has_w32api_windows_h) {
722             print "found.\n";
723         } else {
724             print "NOT found.\n";
725         }
726     }
727
728     if ($DEFINE) {
729         $DEFINE =~ s/^\s+//;
730         if (open(XDEFINE, ">xdefine")) {
731             print XDEFINE $DEFINE, "\n";
732             close(XDEFINE);
733         }
734     }
735 }
736
737 sub doMakefile {
738     my @makefileopts = ();
739
740     if ($] >= 5.005) {
741         push (@makefileopts,
742             'AUTHOR'    => 'Jarkko Hietaniemi <jhi@iki.fi>',
743             'ABSTRACT_FROM' => 'HiRes.pm',
744         );
745         $DEFINE .= " -DATLEASTFIVEOHOHFIVE";
746     }
747
748     push (@makefileopts,
749         'NAME'  => 'Time::HiRes',
750         'VERSION_FROM' => 'HiRes.pm', # finds $VERSION
751         'LIBS'  => $LIBS,   # e.g., '-lm'
752         'DEFINE'        => $DEFINE,     # e.g., '-DHAS_SOMETHING'
753         'XSOPT' => $XSOPT,
754           # Do not even think about 'INC' => '-I/usr/ucbinclude',
755           # Solaris will avenge.
756         'INC'   => '',     # e.g., '-I/usr/include/other'
757         'INSTALLDIRS' => ($] >= 5.008 ? 'perl' : 'site'),
758         'dist'      => {
759             'CI'       => 'ci -l',
760             'COMPRESS' => 'gzip -9f',
761             'SUFFIX'   => 'gz',
762         },
763         clean => { FILES => "xdefine" },
764         realclean => { FILES=> 'const-c.inc const-xs.inc' },
765     );
766
767     if ($ENV{PERL_CORE}) {
768         push @makefileopts, MAN3PODS => {};
769     }
770
771     WriteMakefile(@makefileopts);
772 }
773
774 sub doConstants {
775     if (eval {require ExtUtils::Constant; 1}) {
776         my @names = qw(CLOCK_HIGHRES CLOCK_MONOTONIC
777                        CLOCK_PROCESS_CPUTIME_ID
778                        CLOCK_REALTIME
779                        CLOCK_SOFTTIME
780                        CLOCK_THREAD_CPUTIME_ID
781                        CLOCK_TIMEOFDAY
782                        CLOCKS_PER_SEC
783                        ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF
784                        ITIMER_REALPROF
785                        TIMER_ABSTIME);
786         foreach (qw (d_usleep d_ualarm d_gettimeofday d_getitimer d_setitimer
787                      d_nanosleep d_clock_gettime d_clock_getres
788                      d_clock d_clock_nanosleep d_hires_stat)) {
789             my $macro = $_;
790             if ($macro =~ /^(d_nanosleep|d_clock_gettime|d_clock_getres|d_clock|d_clock_nanosleep)$/) {
791                 $macro =~ s/^d_(.+)/TIME_HIRES_\U$1/;
792             } elsif ($macro =~ /^(d_hires_stat)$/) {
793                 my $d_hires_stat = 0;
794                 $d_hires_stat = $1 if ($DEFINE =~ /-DTIME_HIRES_STAT=(\d+)/);
795                 push @names, {name => $_, macro => "TIME_HIRES_STAT", value => $d_hires_stat,
796                               default => ["IV", "0"]};
797                 next;
798             } else {
799                 $macro =~ s/^d_(.+)/HAS_\U$1/;
800             }
801             push @names, {name => $_, macro => $macro, value => 1,
802                           default => ["IV", "0"]};
803         }
804         ExtUtils::Constant::WriteConstants(
805                                            NAME => 'Time::HiRes',
806                                            NAMES => \@names,
807                                           );
808     } else {
809         my $file;
810         foreach $file ('const-c.inc', 'const-xs.inc') {
811             my $fallback = File::Spec->catfile('fallback', $file);
812             local $/;
813             open IN, "<$fallback" or die "Can't open $fallback: $!";
814             open OUT, ">$file" or die "Can't open $file: $!";
815             print OUT <IN> or die $!;
816             close OUT or die "Can't close $file: $!";
817             close IN or die "Can't close $fallback: $!";
818         }
819     }
820 }
821
822 sub main {
823     print "Configuring Time::HiRes...\n";
824     if ($] == 5.007002) {
825         die "Cannot Configure Time::HiRes for Perl $], aborting.\n";
826     }
827
828     if ($^O =~ /Win32/i) {
829       $DEFINE = '-DSELECT_IS_BROKEN';
830       $LIBS = [];
831       print "System is $^O, skipping full configure...\n";
832     } else {
833       init();
834     }
835     doMakefile;
836     doConstants;
837     my $make = $Config{'make'} || "make";
838     unless (exists $ENV{PERL_CORE} && $ENV{PERL_CORE}) {
839         print  <<EOM;
840 Now you may issue '$make'.  Do not forget also '$make test'.
841 EOM
842        if ((exists $ENV{LC_ALL}   && $ENV{LC_ALL}   =~ /utf-?8/i) ||
843            (exists $ENV{LC_CTYPE} && $ENV{LC_CTYPE} =~ /utf-?8/i) ||
844            (exists $ENV{LANG}     && $ENV{LANG}     =~ /utf-?8/i)) {
845             print  <<EOM;
846 NOTE: if you get an error like this (the Makefile line number may vary):
847 Makefile:91: *** missing separator
848 then set the environment variable LC_ALL to "C" and retry
849 from scratch (re-run perl "Makefile.PL").
850 (And consider upgrading your Perl.)
851 EOM
852         }
853     }
854 }
855
856 &main;
857
858 # EOF