4 use Test::More tests => 65;
7 use File::Path qw( mkpath );
8 use File::Temp qw( tempdir );
9 use ExtUtils::CBuilder::Base;
11 ## N.B. There are pretty severe limits on what can portably be tested
12 ## in the base class. Specifically, don't do anything that will send
13 ## actual compile and link commands to the shell as that won't work
14 ## without the platform-specific overrides.
16 # XXX protect from user CC as we mock everything here
19 my ( $base, $phony, $cwd );
20 my ( $source_file, $object_file, $lib_file );
22 $base = ExtUtils::CBuilder::Base->new();
23 ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
24 isa_ok( $base, 'ExtUtils::CBuilder::Base' );
28 $base = ExtUtils::CBuilder::Base->new(
29 config => { cc => $phony },
31 ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
32 isa_ok( $base, 'ExtUtils::CBuilder::Base' );
33 is( $base->{config}->{cc}, $phony,
34 "Got expected value when 'config' argument passed to new()" );
39 local $ENV{CC} = $phony;
40 $base = ExtUtils::CBuilder::Base->new();
41 ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
42 isa_ok( $base, 'ExtUtils::CBuilder::Base' );
43 is( $base->{config}->{cc}, $phony,
44 "Got expected value \$ENV{CC} set" );
48 my $path_to_perl = $^O eq 'VMS'
49 ? 'perl_root:[000000]perl.exe'
50 : File::Spec->catfile( '', qw| usr bin perl | );
51 local $^X = $path_to_perl;
53 ExtUtils::CBuilder::Base::find_perl_interpreter(),
55 "find_perl_interpreter() returned expected absolute path"
61 skip "Base doesn't know about override on VMS", 1
64 my $path_to_perl = 'foobar';
65 local $^X = $path_to_perl;
66 # %Config is read-only. We cannot assign to it and we therefore cannot
67 # simulate the condition that would occur were its value something other
68 # than an existing file.
69 if ( !$ENV{PERL_CORE} and $Config::Config{perlpath}) {
71 ExtUtils::CBuilder::Base::find_perl_interpreter(),
72 $Config::Config{perlpath},
73 "find_perl_interpreter() returned expected file"
77 local $^X = $path_to_perl = File::Spec->rel2abs($path_to_perl);
79 ExtUtils::CBuilder::Base::find_perl_interpreter(),
81 "find_perl_interpreter() returned expected name"
88 my $tdir = tempdir(CLEANUP => 1);
90 $base = ExtUtils::CBuilder::Base->new();
91 ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
92 isa_ok( $base, 'ExtUtils::CBuilder::Base' );
93 is( scalar keys %{$base->{files_to_clean}}, 0,
94 "No files needing cleaning yet" );
96 my $file_for_cleaning = File::Spec->catfile( $tdir, 'foobar' );
97 open my $IN, '>', $file_for_cleaning
98 or die "Unable to open dummy file: $!";
100 close $IN or die "Unable to close dummy file: $!";
102 $base->add_to_cleanup( $file_for_cleaning );
103 is( scalar keys %{$base->{files_to_clean}}, 1,
104 "One file needs cleaning" );
107 ok( ! -f $file_for_cleaning, "File was cleaned up" );
112 # fake compiler is perl and will always succeed
113 $base = ExtUtils::CBuilder::Base->new(
115 cc => File::Spec->rel2abs($^X) . " -e1 --",
116 ld => File::Spec->rel2abs($^X) . " -e1 --",
119 ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
120 isa_ok( $base, 'ExtUtils::CBuilder::Base' );
122 $base->compile(foo => 'bar');
126 qr/Missing 'source' argument to compile/,
127 "Got expected error message when lacking 'source' argument to compile()"
130 $base = ExtUtils::CBuilder::Base->new( quiet => 1 );
131 ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
132 isa_ok( $base, 'ExtUtils::CBuilder::Base' );
134 $source_file = File::Spec->catfile('t', 'baset.c');
135 create_c_source_file($source_file);
136 ok(-e $source_file, "source file '$source_file' created");
138 # object filename automatically assigned
139 my $obj_ext = $base->{config}{obj_ext};
140 is( $base->object_file($source_file),
141 File::Spec->catfile('t', "baset$obj_ext"),
142 "object_file(): got expected automatically assigned name for object file"
149 local $ENV{PERL_CORE} = '' unless $ENV{PERL_CORE};
150 my $include_dir = $base->perl_inc();
151 ok( $include_dir, "perl_inc() returned true value" );
152 ok( -d $include_dir, "perl_inc() returned directory" );
155 $base = ExtUtils::CBuilder::Base->new( quiet => 1 );
156 ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
157 isa_ok( $base, 'ExtUtils::CBuilder::Base' );
159 $source_file = File::Spec->catfile('t', 'baset.c');
160 create_c_source_file($source_file);
161 ok(-e $source_file, "source file '$source_file' created");
164 my @defines = $base->arg_defines( %args );
165 ok( ! @defines, "Empty hash passed to arg_defines() returns empty list" );
167 my @epsilon = ( epsilon => 'zeta' );
168 my @eta = ( eta => 'theta' );
169 my @alpha = ( alpha => 'beta' );
170 my @gamma = ( gamma => 'delta' );
171 my @all = (\@epsilon, \@eta, \@alpha, \@gamma);
173 %args = map { @{$_} } @all;
174 @defines = $base->arg_defines( %args );
175 my $defines_seen_ref = { map { $_ => 1 } @defines };
176 my $defines_expected_ref;
178 $defines_expected_ref->{"-D$r->[0]=$r->[1]"} = 1;
182 $defines_expected_ref,
183 "arg_defines(): got expected defines",
185 my $ordered_defines_expected_ref = [ sort keys %{$defines_expected_ref} ];
186 is_deeply(\@defines, $ordered_defines_expected_ref,
187 "Got expected order of defines: RT #124106");
189 my $include_dirs_seen_ref =
190 { map {$_ => 1} $base->arg_include_dirs( qw| alpha beta gamma | ) };
192 $include_dirs_seen_ref,
193 { '-Ialpha' => 1, '-Ibeta' => 1, '-Igamma' => 1 },
194 "arg_include_dirs(): got expected include_dirs",
197 is( '-c', $base->arg_nolink(), "arg_nolink(): got expected value" );
200 { map {$_ => 1} $base->arg_object_file('alpha') };
203 { '-o' => 1, 'alpha' => 1 },
204 "arg_object_file(): got expected option flag and value",
207 $seen_ref = { map {$_ => 1} $base->arg_share_object_file('alpha') };
208 my %exp = map {$_ => 1} $base->split_like_shell($base->{config}{lddlflags});
215 "arg_share_object_file(): got expected option flag and value",
219 { map {$_ => 1} $base->arg_exec_file('alpha') };
222 { '-o' => 1, 'alpha' => 1 },
223 "arg_exec_file(): got expected option flag and value",
226 ok(! $base->split_like_shell(undef),
227 "split_like_shell(): handled undefined argument as expected" );
229 my $array_ref = [ qw| alpha beta gamma | ];
230 my %split_seen = map { $_ => 1 } $base->split_like_shell($array_ref);
231 %exp = ( alpha => 1, beta => 1, gamma => 1 );
232 is_deeply( \%split_seen, \%exp,
233 "split_like_shell(): handled array ref as expected" );
237 my $tdir = tempdir(CLEANUP => 1);
238 my $subdir = File::Spec->catdir(
239 $tdir, qw| alpha beta gamma delta epsilon
240 zeta eta theta iota kappa lambda |
242 mkpath($subdir, { mode => 0711 } );
244 or die "Unable to change to temporary directory for testing";
245 local $ENV{PERL_CORE} = 1;
247 local $SIG{__WARN__} = sub { $capture = $_[0] };
248 my $expected_message =
249 qr/PERL_CORE is set but I can't find your perl source!/; #'
252 $rv = $base->perl_src();
253 is( $rv, q{}, "perl_src(): returned empty string as expected" );
254 like( $capture, $expected_message,
255 "perl_src(): got expected warning" );
258 my $config = File::Spec->catfile( $subdir, 'config_h.SH' );
260 $rv = $base->perl_src();
261 is( $rv, q{}, "perl_src(): returned empty string as expected" );
262 like( $capture, $expected_message,
263 "perl_src(): got expected warning" );
266 my $perlh = File::Spec->catfile( $subdir, 'perl.h' );
268 $rv = $base->perl_src();
269 is( $rv, q{}, "perl_src(): returned empty string as expected" );
270 like( $capture, $expected_message,
271 "perl_src(): got expected warning" );
274 my $libsubdir = File::Spec->catdir( $subdir, 'lib' );
275 mkpath($libsubdir, { mode => 0711 } );
276 my $exporter = File::Spec->catfile( $libsubdir, 'Exporter.pm' );
277 touch_file($exporter);
278 $rv = $base->perl_src();
279 ok( -d $rv, "perl_src(): returned a directory" );
280 my $rp = Cwd::realpath($subdir);
282 if ($^O eq 'dec_osf' && $rp =~ m[^/cluster/members/]) {
283 skip "Tru64 cluster filesystem", 1;
285 elsif ($^O eq 'os390') {
286 # os390 also has cluster-like things called 'sysplexed'. So far, the
287 # tail end of the path matches what we passed it (with some prepended
288 # directories). So test for that.
289 like( uc($rp), qr/\U\Q$rp\E$/, "perl_src(): identified directory" );
292 is( uc($rv), uc($rp), "perl_src(): identified directory" );
295 is( $capture, q{}, "perl_src(): no warning, as expected" );
298 or die "Unable to change from temporary directory after testing";
301 my ($dl_file_out, $mksymlists_args);
304 dl_vars => [ qw| alpha beta gamma | ],
306 'Homer::Iliad' => [ qw(trojans greeks) ],
307 'Homer::Odyssey' => [ qw(travellers family suitors) ],
309 dl_func_list => [ qw| delta epsilon | ],
310 dl_imports => { zeta => 'eta', theta => 'iota' },
311 dl_name => 'Tk::Canvas',
312 dl_base => 'Tk::Canvas.ext',
316 ($dl_file_out, $mksymlists_args) =
317 ExtUtils::CBuilder::Base::_prepare_mksymlists_args(\%args);
318 is( $dl_file_out, $dlf, "_prepare_mksymlists_args(): Got expected name for dl_file" );
319 is_deeply( $mksymlists_args,
321 DL_VARS => [ qw| alpha beta gamma | ],
323 'Homer::Iliad' => [ qw(trojans greeks) ],
324 'Homer::Odyssey' => [ qw(travellers family suitors) ],
326 FUNCLIST => [ qw| delta epsilon | ],
327 IMPORTS => { zeta => 'eta', theta => 'iota' },
328 NAME => 'Tk::Canvas',
329 DLBASE => 'Tk::Canvas.ext',
333 "_prepare_mksymlists_args(): got expected arguments for Mksymlists",
338 dl_name => 'Tk::Canvas',
339 dl_base => 'Tk::Canvas.ext',
341 ($dl_file_out, $mksymlists_args) =
342 ExtUtils::CBuilder::Base::_prepare_mksymlists_args(\%args);
343 is( $dl_file_out, $dlf, "_prepare_mksymlists_args(): got expected name for dl_file" );
344 is_deeply( $mksymlists_args,
350 NAME => 'Tk::Canvas',
351 DLBASE => 'Tk::Canvas.ext',
355 "_prepare_mksymlists_args(): got expected arguments for Mksymlists",
360 LDFLAGS => 'ldflags',
363 while (my ($VAR, $var) = each %testvars) {
365 $base = ExtUtils::CBuilder::Base->new( quiet => 1 );
366 ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
367 isa_ok( $base, 'ExtUtils::CBuilder::Base' );
368 like($base->{config}{$var}, qr/\Q$Config{$var}/,
369 "honours $var from Config.pm");
371 $ENV{$VAR} = "-foo -bar";
372 $base = ExtUtils::CBuilder::Base->new( quiet => 1 );
373 ok( $base, "ExtUtils::CBuilder::Base->new() returned true value" );
374 isa_ok( $base, 'ExtUtils::CBuilder::Base' );
375 like($base->{config}{$var}, qr/\Q$ENV{$VAR}/,
376 "honours $VAR from the environment");
377 like($base->{config}{$var}, qr/\Q$Config{$var}/,
378 "doesn't override $var from Config.pm with $VAR from the environment");
383 for ($source_file, $object_file, $lib_file) {
384 next unless defined $_;
389 pass("Completed all tests in $0");
392 1 while unlink 'BASET.LIS';
393 1 while unlink 'BASET.OPT';
396 sub create_c_source_file {
397 my $source_file = shift;
398 open my $FH, '>', $source_file or die "Can't create $source_file: $!";
399 print $FH "int boot_baset(void) { return 1; }\n";
405 open my $FH, '>', $f or die "Can't create $f: $!";