Fix deparsing of reversed foreach loops,
[p5sagit/p5-mst-13.2.git] / ext / Time / HiRes / Makefile.PL
1 require 5.002;
2
3 use Config;
4 use ExtUtils::MakeMaker;
5 use strict;
6
7 my $VERBOSE = $ENV{VERBOSE};
8 my $DEFINE;
9 my $LIBS = [];
10 my $XSOPT;
11
12 use vars qw($self); # Used in 'sourcing' the hints.
13
14 my $ld_exeext = ($^O eq 'cygwin' ||
15                  $^O eq 'os2' && $Config{ldflags} =~ /-Zexe\b/) ? '.exe' : '';
16
17 unless($ENV{PERL_CORE}) {
18     $ENV{PERL_CORE} = 1 if grep { $_ eq 'PERL_CORE=1' } @ARGV;
19 }
20
21 # Perls 5.002 and 5.003 did not have File::Spec, fake what we need.
22
23 sub my_dirsep {
24     $^O eq 'VMS' ? '.' :
25         $^O =~ /mswin32|netware|djgpp/i ? '\\' :
26             $^O eq 'MacOS' ? ':'
27                 : '/';
28 }
29
30 sub my_catdir {
31     shift;
32     my $catdir = join(my_dirsep, @_);
33     $^O eq 'VMS' ? "[$catdir]" : $catdir;
34 }
35
36 sub my_catfile {
37     shift;
38     return join(my_dirsep, @_) unless $^O eq 'VMS';
39     my $file = pop;
40     return my_catdir (undef, @_) . $file;
41 }
42
43 sub my_updir {
44     shift;
45     $^O eq 'VMS' ? "-" : "..";
46 }
47
48 BEGIN {
49     eval { require File::Spec };
50     if ($@) {
51         *File::Spec::catdir  = \&my_catdir;
52         *File::Spec::updir   = \&my_updir;
53         *File::Spec::catfile = \&my_catfile;
54     }
55 }
56
57 # Avoid 'used only once' warnings.
58 my $nop1 = *File::Spec::catdir;
59 my $nop2 = *File::Spec::updir;
60 my $nop3 = *File::Spec::catfile;
61
62 # if you have 5.004_03 (and some slightly older versions?), xsubpp
63 # tries to generate line numbers in the C code generated from the .xs.
64 # unfortunately, it is a little buggy around #ifdef'd code.
65 # my choice is leave it in and have people with old perls complain
66 # about the "Usage" bug, or leave it out and be unable to compile myself
67 # without changing it, and then I'd always forget to change it before a
68 # release. Sorry, Edward :)
69
70 sub try_compile_and_link {
71     my ($c, %args) = @_;
72
73     my ($ok) = 0;
74     my ($tmp) = "tmp$$";
75     local(*TMPC);
76
77     my $obj_ext = $Config{obj_ext} || ".o";
78     unlink("$tmp.c", "$tmp$obj_ext");
79
80     if (open(TMPC, ">$tmp.c")) {
81         print TMPC $c;
82         close(TMPC);
83
84         my $cccmd = $args{cccmd};
85
86         my $errornull;
87
88         my $COREincdir;
89
90         if ($ENV{PERL_CORE}) {
91             my $updir = File::Spec->updir;
92             $COREincdir = File::Spec->catdir(($updir) x 3);
93         } else {
94             $COREincdir = File::Spec->catdir($Config{'archlibexp'}, 'CORE');
95         }
96
97         my $ccflags = $Config{'ccflags'} . ' ' . "-I$COREincdir";
98
99         if ($^O eq 'VMS') {
100             if ($ENV{PERL_CORE}) {
101                 # Fragile if the extensions change hierarchy within
102                 # the Perl core but this should do for now.
103                 $cccmd = "$Config{'cc'} /include=([---]) $tmp.c";
104             } else {
105                 my $perl_core = $Config{'installarchlib'};
106                 $perl_core =~ s/\]$/.CORE]/;
107                 $cccmd = "$Config{'cc'} /include=(perl_root:[000000],$perl_core) $tmp.c";
108             }
109         }
110
111         if ($args{silent} || !$VERBOSE) {
112             $errornull = "2>/dev/null" unless defined $errornull;
113         } else {
114             $errornull = '';
115         }
116
117         $cccmd = "$Config{'cc'} -o $tmp $ccflags $tmp.c @$LIBS $errornull"
118             unless defined $cccmd;
119
120        if ($^O eq 'VMS') {
121             open( CMDFILE, ">$tmp.com" );
122             print CMDFILE "\$ SET MESSAGE/NOFACILITY/NOSEVERITY/NOIDENT/NOTEXT\n";
123             print CMDFILE "\$ $cccmd\n";
124             print CMDFILE "\$ IF \$SEVERITY .NE. 1 THEN EXIT 44\n"; # escalate
125             close CMDFILE;
126             system("\@ $tmp.com");
127             $ok = $?==0;
128             for ("$tmp.c", "$tmp$obj_ext", "$tmp.com", "$tmp$Config{exe_ext}") {
129                 1 while unlink $_;
130             }
131         }
132         else
133         {
134             my $tmp_exe = "$tmp$ld_exeext";
135             printf "cccmd = $cccmd\n" if $VERBOSE;
136             my $res = system($cccmd);
137             $ok = defined($res) && $res==0 && -s $tmp_exe && -x _;
138             unlink("$tmp.c", $tmp_exe);
139         }
140     }
141
142     $ok;
143 }
144
145 sub has_gettimeofday {
146     # confusing but true (if condition true ==> -DHAS_GETTIMEOFDAY already)
147     return 0 if $Config{d_gettimeod} eq 'define';
148     return 1 if try_compile_and_link(<<EOM);
149 #include "EXTERN.h"
150 #include "perl.h"
151 #include "XSUB.h"
152 #ifdef I_SYS_TYPES
153 #   include <sys/types.h>
154 #endif
155
156 #ifdef I_SYS_TIME
157 #   include <sys/time.h>
158 #endif
159
160 #ifdef I_SYS_SELECT
161 #   include <sys/select.h>      /* struct timeval might be hidden in here */
162 #endif
163 static int foo()
164 {
165     struct timeval tv;
166     gettimeofday(&tv, 0);
167 }
168 int main _((int argc, char** argv, char** env))
169 {
170     foo();
171 }
172 EOM
173     return 0;
174 }
175
176 sub has_x {
177     my ($x, %args) = @_;
178
179     return 1 if
180     try_compile_and_link(<<EOM, %args);
181 #include "EXTERN.h"
182 #include "perl.h"
183 #include "XSUB.h"
184
185 #ifdef I_UNISTD
186 #   include <unistd.h>
187 #endif
188
189 #ifdef I_SYS_TYPES
190 #   include <sys/types.h>
191 #endif
192
193 #ifdef I_SYS_TIME
194 #   include <sys/time.h>
195 #endif
196
197 int main _((int argc, char** argv, char** env))
198 {
199         $x;
200 }
201 EOM
202     return 0;
203 }
204
205 sub has_include {
206     my ($inc) = @_;
207     return 1 if
208     try_compile_and_link(<<EOM);
209 #include "EXTERN.h"
210 #include "perl.h"
211 #include "XSUB.h"
212
213 #include <$inc>
214 int main _((int argc, char** argv, char** env))
215 {
216         return 0;
217 }
218 EOM
219     return 0;
220 }
221
222 sub init {
223     my $hints = File::Spec->catfile("hints", "$^O.pl");
224     if (-f $hints) {
225         print "Using hints $hints...\n";
226         local $self;
227         do $hints;
228         if (exists $self->{LIBS}) {
229             $LIBS = $self->{LIBS};
230             print "Extra libraries: @$LIBS...\n";
231         }
232     }
233
234     $DEFINE = '';
235
236     print "Looking for gettimeofday()... ";
237     my $has_gettimeofday;
238     if (exists $Config{d_gettimeod}) {
239         $has_gettimeofday++ if $Config{d_gettimeod};
240     } elsif (has_gettimeofday()) {
241         $DEFINE .= ' -DHAS_GETTIMEOFDAY';
242         $has_gettimeofday++;
243     }
244
245     if ($has_gettimeofday) {
246         print "found.\n";
247     } else {
248         die <<EOD
249 Your operating system does not seem to have the gettimeofday() function.
250 (or, at least, I cannot find it)
251
252 There is no way Time::HiRes is going to work.
253
254 I am awfully sorry but I cannot go further.
255
256 Aborting configuration.
257
258 EOD
259     }
260
261     print "Looking for setitimer()... ";
262     my $has_setitimer;
263     if (exists $Config{d_setitimer}) {
264         $has_setitimer++ if $Config{d_setitimer};
265     } elsif (has_x("setitimer(ITIMER_REAL, 0, 0)")) {
266         $has_setitimer++;
267         $DEFINE .= ' -DHAS_SETITIMER';
268     }
269
270     if ($has_setitimer) {
271         print "found.\n";
272     } else {
273         print "NOT found.\n";
274     }
275
276     print "Looking for getitimer()... ";
277     my $has_getitimer;
278     if (exists $Config{'d_getitimer'}) {
279         $has_getitimer++ if $Config{'d_getitimer'};
280     } elsif (has_x("getitimer(ITIMER_REAL, 0)")) {
281         $has_getitimer++;
282         $DEFINE .= ' -DHAS_GETITIMER';
283     }
284
285     if ($has_getitimer) {
286         print "found.\n";
287     } else {
288         print "NOT found.\n";
289     }
290
291     if ($has_setitimer && $has_getitimer) {
292         print "You have interval timers (both setitimer and getitimer).\n";
293     } else {
294         print "You do not have interval timers.\n";
295     }
296
297     print "Looking for ualarm()... ";
298     my $has_ualarm;
299     if (exists $Config{d_ualarm}) {
300         $has_ualarm++ if $Config{d_ualarm};
301     } elsif (has_x ("ualarm (0, 0)")) {
302         $has_ualarm++;
303         $DEFINE .= ' -DHAS_UALARM';
304     }
305
306     if ($has_ualarm) {
307         print "found.\n";
308     } else {
309         print "NOT found.\n";
310         if ($has_setitimer) {
311             print "But you have setitimer().\n";
312             print "We can make a Time::HiRes::ualarm().\n";
313         }
314     }
315
316     print "Looking for usleep()... ";
317     my $has_usleep;
318     if (exists $Config{d_usleep}) {
319         $has_usleep++ if $Config{d_usleep};
320     } elsif (has_x ("usleep (0)")) {
321         $has_usleep++;
322         $DEFINE .= ' -DHAS_USLEEP';
323     }
324
325     if ($has_usleep) {
326         print "found.\n";
327     } else {
328         print "NOT found.\n";
329         print "Let's see if you have select()... ";
330         if ($Config{'d_select'} eq 'define') {
331             print "found.\n";
332             print "We can make a Time::HiRes::usleep().\n";
333         } else {
334             print "NOT found.\n";
335             print "You won't have a Time::HiRes::usleep().\n";
336         }
337     }
338
339     print "Looking for nanosleep()... ";
340     my $has_nanosleep;
341     if (exists $Config{d_nanosleep}) {
342         if ($Config{d_nanosleep}) {
343             $has_nanosleep++;
344             $DEFINE .= ' -DTIME_HIRES_NANOSLEEP';
345         }
346     } elsif ($^O ne 'mpeix' && # MPE/iX falsely finds nanosleep.
347              has_x ("nanosleep (NULL, NULL)")) {
348         $has_nanosleep++;
349         $DEFINE .= ' -DTIME_HIRES_NANOSLEEP';
350     }
351
352     if ($has_nanosleep) {
353         print "found.\n";
354         print "You can mix subsecond sleeps with signals, if you want to.\n";
355         print "(It's still not portable, though.)\n";
356     } else {
357         print "NOT found.\n";
358         my $nt = ($^O eq 'os2' ? '' : 'not');
359         print "You can$nt mix subsecond sleeps with signals.\n";
360         print "(It would not be portable anyway.)\n";
361     }
362
363     my $has_w32api_windows_h;
364     if ($^O eq 'cygwin') {
365         print "Looking for <w32api/windows.h>... ";
366         if (has_include('w32api/windows.h')) {
367             $has_w32api_windows_h++;
368             $DEFINE .= ' -DHAS_W32API_WINDOWS_H';
369         }
370         if ($has_w32api_windows_h) {
371             print "found.\n";
372         } else {
373             print "NOT found.\n";
374         }
375     }
376
377     if ($DEFINE) {
378         $DEFINE =~ s/^\s+//;
379         if (open(XDEFINE, ">xdefine")) {
380             print XDEFINE $DEFINE, "\n";
381             close(XDEFINE);
382         }
383     }
384 }
385
386 sub doMakefile {
387     my @makefileopts = ();
388
389     if ($] >= 5.005) {
390         push (@makefileopts,
391             'AUTHOR'    => 'Jarkko Hietaniemi <jhi@iki.fi>',
392             'ABSTRACT_FROM' => 'HiRes.pm',
393         );
394         $DEFINE .= " -DATLEASTFIVEOHOHFIVE";
395     }
396
397     push (@makefileopts,
398         'NAME'  => 'Time::HiRes',
399         'VERSION_FROM' => 'HiRes.pm', # finds $VERSION
400         'LIBS'  => $LIBS,   # e.g., '-lm'
401         'DEFINE'        => $DEFINE,     # e.g., '-DHAS_SOMETHING'
402         'XSOPT' => $XSOPT,
403     # do not even think about 'INC' => '-I/usr/ucbinclude', Solaris will avenge.
404         'INC'   => '',     # e.g., '-I/usr/include/other'
405         'INSTALLDIRS' => 'perl',
406         'dist'      => {
407             'CI'       => 'ci -l',
408             'COMPRESS' => 'gzip -9f',
409             'SUFFIX'   => 'gz',
410         },
411         clean => { FILES => "xdefine" },
412         realclean => { FILES=> 'const-c.inc const-xs.inc' },
413     );
414
415     if ($ENV{PERL_CORE}) {
416         push @makefileopts, MAN3PODS => {};
417     }
418
419     WriteMakefile(@makefileopts);
420 }
421
422 sub doConstants {
423     if (eval {require ExtUtils::Constant; 1}) {
424         my @names = (qw(ITIMER_REAL ITIMER_VIRTUAL ITIMER_PROF
425                         ITIMER_REALPROF));
426         foreach (qw (d_usleep d_ualarm d_gettimeofday d_getitimer d_setitimer
427                      d_nanosleep)) {
428             my $macro = $_;
429             if ($macro eq 'd_nanosleep') {
430                 $macro =~ s/d_(.*)/TIME_HIRES_\U$1/;
431             } else {
432                 $macro =~ s/d_(.*)/HAS_\U$1/;
433             }
434             push @names, {name => $_, macro => $macro, value => 1,
435                           default => ["IV", "0"]};
436         }
437         ExtUtils::Constant::WriteConstants(
438                                            NAME => 'Time::HiRes',
439                                            NAMES => \@names,
440                                           );
441     } else {
442         my $file;
443         foreach $file ('const-c.inc', 'const-xs.inc') {
444             my $fallback = File::Spec->catfile('fallback', $file);
445             local $/;
446             open IN, "<$fallback" or die "Can't open $fallback: $!";
447             open OUT, ">$file" or die "Can't open $file: $!";
448             print OUT <IN> or die $!;
449             close OUT or die "Can't close $file: $!";
450             close IN or die "Can't close $fallback: $!";
451         }
452     }
453 }
454
455 sub main {
456     print "Configuring Time::HiRes...\n";
457     if ($] == 5.007002) {
458         die "Cannot Configure Time::HiRes for Perl $], aborting.\n";
459     }
460
461     if ($^O =~ /Win32/i) {
462       $DEFINE = '-DSELECT_IS_BROKEN';
463       $LIBS = [];
464     } else {
465       init();
466     }
467     doMakefile;
468     doConstants;
469     my $make = $Config{'make'} || "make";
470     unless (exists $ENV{PERL_CORE} && $ENV{PERL_CORE}) {
471         print  <<EOM;
472 Now you may issue '$make'.  Do not forget also '$make test'.
473 EOM
474        if ((exists $ENV{LC_ALL}   && $ENV{LC_ALL}   =~ /utf-?8/i) ||
475            (exists $ENV{LC_CTYPE} && $ENV{LC_CTYPE} =~ /utf-?8/i) ||
476            (exists $ENV{LANG}     && $ENV{LANG}     =~ /utf-?8/i)) {
477             print  <<EOM;
478 NOTE: if you get an error like this (the line number may vary):
479 Makefile:91: *** missing separator
480 then set the environment variable LC_ALL to "C" and retry
481 from scratch (re-run perl "Makefile.PL").
482 EOM
483         }
484     }
485 }
486
487 &main;
488
489 # EOF