Update Time::HiRes' Changes file
[p5sagit/p5-mst-13.2.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 #include <time.h>
346 int main(int argc, char** argv)
347 {
348     int ret;
349     struct timespec ts1;
350     struct timespec ts2;
351     ts1.tv_sec  = 0;
352     ts1.tv_nsec = 750000000;;
353     ret = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts1, &ts2);
354     ret == 0 ? exit(0) : exit(errno ? errno : -1);
355 }
356 EOM
357 }
358
359 sub DEFINE {
360     my ($def, $val) = @_;
361     my $define = defined $val ? "$def=$val" : $def ;
362     unless ($DEFINE =~ /(?:^| )-D\Q$define\E(?: |$)/) {
363         $DEFINE .= " -D$define";
364     }
365 }
366
367 sub init {
368     my $hints = File::Spec->catfile("hints", "$^O.pl");
369     if (-f $hints) {
370         print "Using hints $hints...\n";
371         local $self;
372         do $hints;
373         if (exists $self->{LIBS}) {
374             $LIBS = $self->{LIBS};
375             print "Extra libraries: @$LIBS...\n";
376         }
377     }
378
379     $DEFINE = '';
380
381     if ($Config{d_syscall}) {
382         print "Have syscall()... looking for syscall.h... ";
383         if (has_include('syscall.h')) {
384             $SYSCALL_H = 'syscall.h';
385         } elsif (has_include('sys/syscall.h')) {
386             $SYSCALL_H = 'sys/syscall.h';
387         }
388     } else {
389         print "No syscall()...\n";
390     }
391
392     if ($Config{d_syscall}) {
393         if (defined $SYSCALL_H) {
394             print "found <$SYSCALL_H>.\n";
395         } else {
396             print "NOT found.\n";
397         }
398     }
399
400     print "Looking for gettimeofday()... ";
401     my $has_gettimeofday;
402     if (exists $Config{d_gettimeod}) {
403         $has_gettimeofday++ if $Config{d_gettimeod};
404     } elsif (has_gettimeofday()) {
405         $DEFINE .= ' -DHAS_GETTIMEOFDAY';
406         $has_gettimeofday++;
407     }
408
409     if ($has_gettimeofday) {
410         print "found.\n";
411     } else {
412         die <<EOD
413 Your operating system does not seem to have the gettimeofday() function.
414 (or, at least, I cannot find it)
415
416 There is no way Time::HiRes is going to work.
417
418 I am awfully sorry but I cannot go further.
419
420 Aborting configuration.
421
422 EOD
423     }
424
425     print "Looking for setitimer()... ";
426     my $has_setitimer;
427     if (exists $Config{d_setitimer}) {
428         $has_setitimer++ if $Config{d_setitimer};
429     } elsif (has_x("setitimer(ITIMER_REAL, 0, 0)")) {
430         $has_setitimer++;
431         $DEFINE .= ' -DHAS_SETITIMER';
432     }
433
434     if ($has_setitimer) {
435         print "found.\n";
436     } else {
437         print "NOT found.\n";
438     }
439
440     print "Looking for getitimer()... ";
441     my $has_getitimer;
442     if (exists $Config{'d_getitimer'}) {
443         $has_getitimer++ if $Config{'d_getitimer'};
444     } elsif (has_x("getitimer(ITIMER_REAL, 0)")) {
445         $has_getitimer++;
446         $DEFINE .= ' -DHAS_GETITIMER';
447     }
448
449     if ($has_getitimer) {
450         print "found.\n";
451     } else {
452         print "NOT found.\n";
453     }
454
455     if ($has_setitimer && $has_getitimer) {
456         print "You have interval timers (both setitimer and getitimer).\n";
457     } else {
458         print "You do not have interval timers.\n";
459     }
460
461     print "Looking for ualarm()... ";
462     my $has_ualarm;
463     if (exists $Config{d_ualarm}) {
464         $has_ualarm++ if $Config{d_ualarm};
465     } elsif (has_x ("ualarm (0, 0)")) {
466         $has_ualarm++;
467         $DEFINE .= ' -DHAS_UALARM';
468     }
469
470     if ($has_ualarm) {
471         print "found.\n";
472     } else {
473         print "NOT found.\n";
474         if ($has_setitimer) {
475             print "But you have setitimer().\n";
476             print "We can make a Time::HiRes::ualarm().\n";
477         }
478     }
479
480     print "Looking for usleep()... ";
481     my $has_usleep;
482     if (exists $Config{d_usleep}) {
483         $has_usleep++ if $Config{d_usleep};
484     } elsif (has_x ("usleep (0)")) {
485         $has_usleep++;
486         $DEFINE .= ' -DHAS_USLEEP';
487     }
488
489     if ($has_usleep) {
490         print "found.\n";
491     } else {
492         print "NOT found.\n";
493         print "Let's see if you have select()... ";
494         if ($Config{'d_select'}) {
495             print "found.\n";
496             print "We can make a Time::HiRes::usleep().\n";
497         } else {
498             print "NOT found.\n";
499             print "You won't have a Time::HiRes::usleep().\n";
500         }
501     }
502
503     print "Looking for nanosleep()... ";
504     my $has_nanosleep;
505     if ($ENV{FORCE_NANOSLEEP_SCAN}) {
506         print "forced scan... ";
507         if (has_nanosleep()) {
508             $has_nanosleep++;
509             $DEFINE .= ' -DTIME_HIRES_NANOSLEEP';
510         }
511     }
512     elsif (exists $Config{d_nanosleep}) {
513         print "believing \$Config{d_nanosleep}... ";
514         if ($Config{d_nanosleep}) {
515             $has_nanosleep++;
516             $DEFINE .= ' -DTIME_HIRES_NANOSLEEP';
517         }
518     } elsif ($^O =~ /^(mpeix)$/) {
519         # MPE/iX falsely finds nanosleep from its libc equivalent.
520         print "skipping because in $^O... ";
521     } else {
522         if (has_nanosleep()) {
523             $has_nanosleep++;
524             $DEFINE .= ' -DTIME_HIRES_NANOSLEEP';
525         }
526     }
527
528     if ($has_nanosleep) {
529         print "found.\n";
530         print "You can mix subsecond sleeps with signals, if you want to.\n";
531         print "(It's still not portable, though.)\n";
532     } else {
533         print "NOT found.\n";
534         my $nt = ($^O eq 'os2' ? '' : 'not');
535         print "You can$nt mix subsecond sleeps with signals.\n";
536         print "(It would not be portable anyway.)\n";
537     }
538
539     print "Looking for clock_gettime()... ";
540     my $has_clock_gettime;
541     if (exists $Config{d_clock_gettime}) {
542         $has_clock_gettime++ if $Config{d_clock_gettime}; # Unlikely...
543     } elsif (has_clock_xxx('gettime')) {
544         $has_clock_gettime++;
545         $DEFINE .= ' -DTIME_HIRES_CLOCK_GETTIME';
546     } elsif (defined $SYSCALL_H && has_clock_xxx_syscall('gettime')) {
547         $has_clock_gettime++;
548         $DEFINE .= ' -DTIME_HIRES_CLOCK_GETTIME -DTIME_HIRES_CLOCK_GETTIME_SYSCALL';
549     }
550
551     if ($has_clock_gettime) {
552         if ($DEFINE =~ /-DTIME_HIRES_CLOCK_GETTIME_SYSCALL/) {
553             print "found (via syscall).\n";
554         } else {
555             print "found.\n";
556         }
557     } else {
558         print "NOT found.\n";
559     }
560
561     print "Looking for clock_getres()... ";
562     my $has_clock_getres;
563     if (exists $Config{d_clock_getres}) {
564         $has_clock_getres++ if $Config{d_clock_getres}; # Unlikely...
565     } elsif (has_clock_xxx('getres')) {
566         $has_clock_getres++;
567         $DEFINE .= ' -DTIME_HIRES_CLOCK_GETRES';
568     } elsif (defined $SYSCALL_H && has_clock_xxx_syscall('getres')) {
569         $has_clock_getres++;
570         $DEFINE .= ' -DTIME_HIRES_CLOCK_GETRES -DTIME_HIRES_CLOCK_GETRES_SYSCALL';
571     }
572
573     if ($has_clock_getres) {
574         if ($DEFINE =~ /-DTIME_HIRES_CLOCK_GETRES_SYSCALL/) {
575             print "found (via syscall).\n";
576         } else {
577             print "found.\n";
578         }
579     } else {
580         print "NOT found.\n";
581     }
582
583     print "Looking for clock_nanosleep()... ";
584     my $has_clock_nanosleep;
585     if (exists $Config{d_clock_nanosleep}) {
586         $has_clock_nanosleep++ if $Config{d_clock_nanosleep}; # Unlikely...
587     } elsif (has_clock_nanosleep()) {
588         $has_clock_nanosleep++;
589         $DEFINE .= ' -DTIME_HIRES_CLOCK_NANOSLEEP';
590     }
591
592     if ($has_clock_nanosleep) {
593         print "found.\n";
594     } else {
595         print "NOT found.\n";
596     }
597
598     print "Looking for clock()... ";
599     my $has_clock;
600     if (exists $Config{d_clock}) {
601         $has_clock++ if $Config{d_clock}; # Unlikely...
602     } elsif (has_clock()) {
603         $has_clock++;
604         $DEFINE .= ' -DTIME_HIRES_CLOCK';
605     }
606
607     if ($has_clock) {
608         print "found.\n";
609     } else {
610         print "NOT found.\n";
611     }
612
613     print "Looking for stat() subsecond timestamps...\n";
614
615     print "Trying struct stat st_atimespec.tv_nsec...";
616     my $has_stat_st_xtimespec;
617     if (try_compile_and_link(<<EOM)) {
618 $TIME_HEADERS
619 #include <sys/stat.h>
620 int main(int argc, char** argv) {
621     struct stat st;
622     st.st_atimespec.tv_nsec = 0;
623 }
624 EOM
625       $has_stat_st_xtimespec++;
626       DEFINE('TIME_HIRES_STAT', 1);
627     }
628
629     if ($has_stat_st_xtimespec) {
630         print "found.\n";
631     } else {
632         print "NOT found.\n";
633     }
634
635     print "Trying struct stat st_atimensec...";
636     my $has_stat_st_xtimensec;
637     if (try_compile_and_link(<<EOM)) {
638 $TIME_HEADERS
639 #include <sys/stat.h>
640 int main(int argc, char** argv) {
641     struct stat st;
642     st.st_atimensec = 0;
643 }
644 EOM
645       $has_stat_st_xtimensec++;
646       DEFINE('TIME_HIRES_STAT', 2);
647     }
648
649     if ($has_stat_st_xtimensec) {
650         print "found.\n";
651     } else {
652         print "NOT found.\n";
653     }
654
655     print "Trying struct stat st_atime_n...";
656     my $has_stat_st_xtime_n;
657     if (try_compile_and_link(<<EOM)) {
658 $TIME_HEADERS
659 #include <sys/stat.h>
660 int main(int argc, char** argv) {
661     struct stat st;
662     st.st_atime_n = 0;
663 }
664 EOM
665       $has_stat_st_xtime_n++;
666       DEFINE('TIME_HIRES_STAT', 3);
667     }
668
669     if ($has_stat_st_xtime_n) {
670         print "found.\n";
671     } else {
672         print "NOT found.\n";
673     }
674
675     print "Trying struct stat st_atim.tv_nsec...";
676     my $has_stat_st_xtim;
677     if (try_compile_and_link(<<EOM)) {
678 $TIME_HEADERS
679 #include <sys/stat.h>
680 int main(int argc, char** argv) {
681     struct stat st;
682     st.st_atim.tv_nsec = 0;
683 }
684 EOM
685       $has_stat_st_xtim++;
686       DEFINE('TIME_HIRES_STAT', 4);
687     }
688
689     if ($has_stat_st_xtim) {
690         print "found.\n";
691     } else {
692         print "NOT found.\n";
693     }
694
695     print "Trying struct stat st_uatime...";
696     my $has_stat_st_uxtime;
697     if (try_compile_and_link(<<EOM)) {
698 $TIME_HEADERS
699 #include <sys/stat.h>
700 int main(int argc, char** argv) {
701     struct stat st;
702     st.st_uatime = 0;
703 }
704 EOM
705       $has_stat_st_uxtime++;
706       DEFINE('TIME_HIRES_STAT', 5);
707     }
708
709     if ($has_stat_st_uxtime) {
710         print "found.\n";
711     } else {
712         print "NOT found.\n";
713     }
714
715    if ($DEFINE =~ /-DTIME_HIRES_STAT=\d+/) {
716     print "You seem to have stat() subsecond timestamps.\n";
717     print "(Your struct stat has them, but the filesystems must help.)\n";
718    } else {
719     print "You do not seem to have stat subsecond timestamps.\n";
720    }
721
722     my $has_w32api_windows_h;
723
724     if ($^O eq 'cygwin') {
725         print "Looking for <w32api/windows.h>... ";
726         if (has_include('w32api/windows.h')) {
727             $has_w32api_windows_h++;
728             DEFINE('HAS_W32API_WINDOWS_H');
729         }
730         if ($has_w32api_windows_h) {
731             print "found.\n";
732         } else {
733             print "NOT found.\n";
734         }
735     }
736
737     if ($DEFINE) {
738         $DEFINE =~ s/^\s+//;
739         if (open(XDEFINE, ">xdefine")) {
740             print XDEFINE $DEFINE, "\n";
741             close(XDEFINE);
742         }
743     }
744 }
745
746 sub doMakefile {
747     my @makefileopts = ();
748
749     if ($] >= 5.005) {
750         push (@makefileopts,
751             'AUTHOR'    => 'Jarkko Hietaniemi <jhi@iki.fi>',
752             'ABSTRACT_FROM' => 'HiRes.pm',
753         );
754         DEFINE('ATLEASTFIVEOHOHFIVE');
755     }
756
757     push (@makefileopts,
758         'NAME'  => 'Time::HiRes',
759         'VERSION_FROM' => 'HiRes.pm', # finds $VERSION
760         'LIBS'  => $LIBS,   # e.g., '-lm'
761         'DEFINE'        => $DEFINE,     # e.g., '-DHAS_SOMETHING'
762         'XSOPT' => $XSOPT,
763           # Do not even think about 'INC' => '-I/usr/ucbinclude',
764           # Solaris will avenge.
765         'INC'   => '',     # e.g., '-I/usr/include/other'
766         'INSTALLDIRS' => ($] >= 5.008 ? 'perl' : 'site'),
767         'dist'      => {
768             'CI'       => 'ci -l',
769             'COMPRESS' => 'gzip -9f',
770             'SUFFIX'   => 'gz',
771         },
772         clean => { FILES => "xdefine" },
773         realclean => { FILES=> 'const-c.inc const-xs.inc' },
774     );
775
776     if ($ENV{PERL_CORE}) {
777         push @makefileopts, MAN3PODS => {};
778     }
779
780     WriteMakefile(@makefileopts);
781 }
782
783 sub doConstants {
784     if (eval {require ExtUtils::Constant; 1}) {
785         my @names = qw(CLOCK_HIGHRES CLOCK_MONOTONIC
786                        CLOCK_PROCESS_CPUTIME_ID
787                        CLOCK_REALTIME
788                        CLOCK_SOFTTIME
789                        CLOCK_THREAD_CPUTIME_ID
790                        CLOCK_TIMEOFDAY
791                        CLOCKS_PER_SEC
792                        ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF
793                        ITIMER_REALPROF
794                        TIMER_ABSTIME);
795         foreach (qw (d_usleep d_ualarm d_gettimeofday d_getitimer d_setitimer
796                      d_nanosleep d_clock_gettime d_clock_getres
797                      d_clock d_clock_nanosleep d_hires_stat)) {
798             my $macro = $_;
799             if ($macro =~ /^(d_nanosleep|d_clock_gettime|d_clock_getres|d_clock|d_clock_nanosleep)$/) {
800                 $macro =~ s/^d_(.+)/TIME_HIRES_\U$1/;
801             } elsif ($macro =~ /^(d_hires_stat)$/) {
802                 my $d_hires_stat = 0;
803                 $d_hires_stat = $1 if ($DEFINE =~ /-DTIME_HIRES_STAT=(\d+)/);
804                 push @names, {name => $_, macro => "TIME_HIRES_STAT", value => $d_hires_stat,
805                               default => ["IV", "0"]};
806                 next;
807             } else {
808                 $macro =~ s/^d_(.+)/HAS_\U$1/;
809             }
810             push @names, {name => $_, macro => $macro, value => 1,
811                           default => ["IV", "0"]};
812         }
813         ExtUtils::Constant::WriteConstants(
814                                            NAME => 'Time::HiRes',
815                                            NAMES => \@names,
816                                           );
817     } else {
818         my $file;
819         foreach $file ('const-c.inc', 'const-xs.inc') {
820             my $fallback = File::Spec->catfile('fallback', $file);
821             local $/;
822             open IN, "<$fallback" or die "Can't open $fallback: $!";
823             open OUT, ">$file" or die "Can't open $file: $!";
824             print OUT <IN> or die $!;
825             close OUT or die "Can't close $file: $!";
826             close IN or die "Can't close $fallback: $!";
827         }
828     }
829 }
830
831 sub main {
832     print "Configuring Time::HiRes...\n";
833     if ($] == 5.007002) {
834         die "Cannot Configure Time::HiRes for Perl $], aborting.\n";
835     }
836
837     if ($^O =~ /Win32/i) {
838       DEFINE('SELECT_IS_BROKEN');
839       $LIBS = [];
840       print "System is $^O, skipping full configure...\n";
841     } else {
842       init();
843     }
844     doMakefile;
845     doConstants;
846     my $make = $Config{'make'} || "make";
847     unless (exists $ENV{PERL_CORE} && $ENV{PERL_CORE}) {
848         print  <<EOM;
849 Now you may issue '$make'.  Do not forget also '$make test'.
850 EOM
851        if ((exists $ENV{LC_ALL}   && $ENV{LC_ALL}   =~ /utf-?8/i) ||
852            (exists $ENV{LC_CTYPE} && $ENV{LC_CTYPE} =~ /utf-?8/i) ||
853            (exists $ENV{LANG}     && $ENV{LANG}     =~ /utf-?8/i)) {
854             print  <<EOM;
855 NOTE: if you get an error like this (the Makefile line number may vary):
856 Makefile:91: *** missing separator
857 then set the environment variable LC_ALL to "C" and retry
858 from scratch (re-run perl "Makefile.PL").
859 (And consider upgrading your Perl.)
860 EOM
861         }
862     }
863 }
864
865 &main;
866
867 # EOF