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