1 package MakeMaker::Test::Utils;
8 our @ISA = qw(Exporter);
10 our $Is_VMS = $^O eq 'VMS';
11 our $Is_MacOS = $^O eq 'MacOS';
13 our @EXPORT = qw(which_perl perl_lib makefile_name makefile_backup
14 make make_run run make_macro calibrate_mtime
22 # Setup the code to clean out %ENV
24 # Environment variables which might effect our testing
25 my @delete_env_keys = qw(
35 # Remember the ENV values because on VMS %ENV is global
36 # to the user, not the process.
40 for my $key (@delete_env_keys) {
41 if( exists $ENV{$key} ) {
42 $restore_env_keys{$key} = delete $ENV{$key};
51 while( my($key, $val) = each %restore_env_keys ) {
61 MakeMaker::Test::Utils - Utility routines for testing MakeMaker
65 use MakeMaker::Test::Utils;
67 my $perl = which_perl;
70 my $makefile = makefile_name;
71 my $makefile_back = makefile_backup;
74 my $make_run = make_run;
75 make_macro($make, $targ, %macros);
77 my $mtime = calibrate_mtime;
81 my $have_compiler = have_compiler();
83 my $text = slurp($filename);
88 A consolidation of little utility functions used through out the
93 The following are exported by default.
99 my $perl = which_perl;
101 Returns a path to perl which is safe to use in a command line, no
102 matter where you chdir to.
110 # VMS should have 'perl' aliased properly
111 return $perl if $Is_VMS;
113 $perl .= $Config{exe_ext} unless $perl =~ m/$Config{exe_ext}$/i;
115 my $perlpath = File::Spec->rel2abs( $perl );
116 unless( $Is_MacOS || -x $perlpath ) {
117 # $^X was probably 'perl'
119 # When building in the core, *don't* go off and find
121 die "Can't find a perl to use (\$^X=$^X), (\$perlpath=$perlpath)"
124 foreach my $path (File::Spec->path) {
125 $perlpath = File::Spec->catfile($path, $perl);
126 last if -x $perlpath;
137 Sets up environment variables so perl can find its libraries.
138 Run this before changing directories.
142 my $old5lib = $ENV{PERL5LIB};
143 my $had5lib = exists $ENV{PERL5LIB};
145 if ($ENV{PERL_CORE}) {
146 # Whilst we'll be running in perl-src/cpan/$distname/t/
147 # instead of blib, our code will be copied with all the other code to
148 # the top-level library.
149 # $ENV{PERL5LIB} will be set with this, but (by default) it's a relative
151 $ENV{PERL5LIB} = join $Config{path_sep}, map {
152 File::Spec->rel2abs($_) } split quotemeta($Config{path_sep}), $ENV{PERL5LIB};
153 @INC = map { File::Spec->rel2abs($_) } @INC;
155 my $lib = 'blib/lib';
156 $lib = File::Spec->rel2abs($lib);
158 push @libs, $ENV{PERL5LIB} if exists $ENV{PERL5LIB};
159 $ENV{PERL5LIB} = join($Config{path_sep}, @libs);
166 $ENV{PERL5LIB} = $old5lib;
169 delete $ENV{PERL5LIB};
174 =item B<makefile_name>
176 my $makefile = makefile_name;
178 MakeMaker doesn't always generate 'Makefile'. It returns what it
184 return $Is_VMS ? 'Descrip.MMS' : 'Makefile';
187 =item B<makefile_backup>
189 my $makefile_old = makefile_backup;
191 Returns the name MakeMaker will use for a backup of the current
196 sub makefile_backup {
197 my $makefile = makefile_name;
198 return $Is_VMS ? "$makefile".'_old' : "$makefile.old";
205 Returns a good guess at the make to run.
210 my $make = $Config{make};
211 $make = $ENV{MAKE} if exists $ENV{MAKE};
218 my $make_run = make_run;
220 Returns the make to run as with make() plus any necessary switches.
226 $make .= ' -nologo' if $make eq 'nmake';
233 my $make_cmd = make_macro($make, $target, %macros);
235 Returns the command necessary to run $make on the given $target using
238 my $make_test_verbose = make_macro(make_run(), 'test',
241 This is important because VMS's make utilities have a completely
242 different calling convention than Unix or Windows.
244 %macros is actually a list of tuples, so the order will be preserved.
249 my($make, $target) = (shift, shift);
251 my $is_mms = $make =~ /^MM(K|S)/i;
255 while( my($key,$val) = splice(@_, 0, 2) ) {
257 $macros .= qq{/macro="$key=$val"};
260 $macros .= qq{ $key=$val};
264 return $is_mms ? "$make$macros $target" : "$make $target $macros";
267 =item B<calibrate_mtime>
269 my $mtime = calibrate_mtime;
271 When building on NFS, file modification times can often lose touch
272 with reality. This returns the mtime of a file which has just been
277 sub calibrate_mtime {
278 open(FILE, ">calibrate_mtime.tmp") || die $!;
281 my($mtime) = (stat('calibrate_mtime.tmp'))[9];
282 unlink 'calibrate_mtime.tmp';
288 my $out = run($command);
289 my @out = run($command);
291 Runs the given $command as an external program returning at least STDOUT
292 as $out. If possible it will return STDOUT and STDERR combined as you
293 would expect to see on a screen.
302 # Unix, modern Windows and OS/2 from 5.005_54 up can handle can handle 2>&1
303 # This makes our failure diagnostics nicer to read.
304 if( MM->os_flavor_is('Unix') or
305 (MM->os_flavor_is('Win32') and !MM->os_flavor_is('Win9x')) or
306 ($] > 5.00554 and MM->os_flavor_is('OS/2'))
318 my @out = run_ok($cmd);
320 Like run() but it tests that the result exited normally.
322 The output from run() will be used as a diagnostic if it fails.
327 my $tb = Test::Builder->new;
331 $tb->cmp_ok( $?, '==', 0, "run(@_)" ) || $tb->diag(@out);
333 return wantarray ? @out : join "", @out;
336 =item B<setup_mm_test_root>
338 Creates a rooted logical to avoid the 8-level limit on older VMS systems.
339 No action taken on non-VMS systems.
343 sub setup_mm_test_root {
345 # On older systems we might exceed the 8-level directory depth limit
346 # imposed by RMS. We get around this with a rooted logical, but we
347 # can't create logical names with attributes in Perl, so we do it
348 # in a DCL subprocess and put it in the job table so the parent sees it.
349 open( MMTMP, '>mmtesttmp.com' ) ||
350 die "Error creating command file; $!";
351 print MMTMP <<'COMMAND';
352 $ MM_TEST_ROOT = F$PARSE("SYS$DISK:[--]",,,,"NO_CONCEAL")-".][000000"-"]["-"].;"+".]"
353 $ DEFINE/JOB/NOLOG/TRANSLATION=CONCEALED MM_TEST_ROOT 'MM_TEST_ROOT'
357 system '@mmtesttmp.com';
358 1 while unlink 'mmtesttmp.com';
364 $have_compiler = have_compiler;
366 Returns true if there is a compiler available for XS builds.
371 my $have_compiler = 0;
373 # ExtUtils::CBuilder prints its compilation lines to the screen.
376 local *STDOUT = *STDOUT;
377 local *STDERR = *STDERR;
379 tie *STDOUT, 'TieOut';
380 tie *STDERR, 'TieOut';
383 require ExtUtils::CBuilder;
384 my $cb = ExtUtils::CBuilder->new;
386 $have_compiler = $cb->have_compiler;
389 return $have_compiler;
394 $contents = slurp($filename);
396 Returns the $contents of $filename.
398 Will die if $filename cannot be opened.
403 my $filename = shift;
406 open my $fh, $filename or die "Can't open $filename for reading: $!";
417 Michael G Schwern <schwern@pobox.com>