File Coverage

lib/ExtUtils/Liblist/Kid.pm
Criterion Covered Total %
statement 105 341 30.7
branch 54 254 21.2
condition 22 97 22.6
subroutine 10 21 47.6
pod 0 1 0.0
total 191 714 26.7


line stmt bran cond sub pod time code
1             package ExtUtils::Liblist::Kid;
2              
3             # XXX Splitting this out into its own .pm is a temporary solution.
4              
5             # This kid package is to be used by MakeMaker. It will not work if
6             # $self is not a Makemaker.
7              
8 54     54   1259 use 5.006;
  54         212  
9              
10             # Broken out of MakeMaker from version 4.11
11              
12 54     54   326 use strict;
  54         109  
  54         1455  
13 54     54   289 use warnings;
  54         137  
  54         4791  
14             our $VERSION = '7.78';
15             $VERSION =~ tr/_//d;
16              
17 54     54   1124 use ExtUtils::MakeMaker::Config;
  54         110  
  54         427  
18 54     54   353 use Cwd 'cwd';
  54         127  
  54         4208  
19 54     54   354 use File::Basename;
  54         99  
  54         5536  
20 54     54   330 use File::Spec;
  54         117  
  54         367653  
21              
22             sub ext {
23 168 50   168 0 213906 if ( $^O eq 'VMS' ) { goto &_vms_ext; }
  0 50       0  
24 0         0 elsif ( $^O eq 'MSWin32' ) { goto &_win32_ext; }
25 168         1940 else { goto &_unix_os2_ext; }
26             }
27              
28             sub _space_dirs_split {
29 14     14   92 my ($libpth) = @_;
30 14 100       68 return if !length $libpth;
31 6         27 my (@chunks, @ret);
32 6         195 push @chunks, [$1,$2] while $libpth =~ /(\S+)(\s*)/g;
33 6         39 CHUNK: while (@chunks) {
34 22         64 my ($c, $ind) = (shift(@chunks), 0);
35 22 100       407 if (-d $c->[0]) { push @ret, $c->[0]; next CHUNK; }
  20         3086  
  20         76  
36 2         14 my $sofar = join '', @$c;
37 2         13 while ($ind < @chunks) {
38 1         5 my ($this_word, $this_space) = @{ $chunks[$ind] };
  1         7  
39 1         4 $sofar .= $this_word;
40 1 50       47 if (-d $sofar) { push @ret, $sofar; next CHUNK; }
  1         14  
  1         9  
41 0         0 $sofar .= $this_space;
42 0         0 $ind++;
43             }
44             }
45 6         31 @ret;
46             }
47              
48             sub _unix_os2_ext {
49 168     168   1045 my ( $self, $potential_libs, $verbose, $give_libs ) = @_;
50 168   50     1551 $verbose ||= 0;
51              
52 168 0 33     1842 if ( $^O =~ /os2|android/ and $Config{perllibs} ) {
53              
54             # Dynamic libraries are not transitive, so we may need including
55             # the libraries linked against perl.dll/libperl.so again.
56              
57 0 0       0 $potential_libs .= " " if $potential_libs;
58 0         0 $potential_libs .= $Config{perllibs};
59             }
60 168 100       5010 return ( "", "", "", "", ( $give_libs ? [] : () ) ) unless $potential_libs;
    100          
61 14 50       66 warn "Potential libraries are '$potential_libs':\n" if $verbose;
62              
63 14         125 my ( $so ) = $Config{so};
64 14 50       123 my ( $libs ) = defined $Config{perllibs} ? $Config{perllibs} : $Config{libs};
65 14   100     151 my $Config_libext = $Config{lib_ext} || ".a";
66 14         84 my $Config_dlext = $Config{dlext};
67              
68             # compute $extralibs, $bsloadlibs and $ldloadlibs from
69             # $potential_libs
70             # this is a rewrite of Andy Dougherty's extliblist in perl
71              
72 14         2625 require Text::ParseWords;
73              
74 14         8972 my @searchpath; # from "-L/path" entries in $potential_libs
75 14   100     387 my @libpath = _space_dirs_split($Config{libpth} || '');
76 14         92 my ( @ldloadlibs, @bsloadlibs, @extralibs, @ld_run_path, %ld_run_path_seen );
77 14         0 my ( @libs, %libs_seen );
78 14         0 my ( $fullname, @fullname );
79 14         92273 my ( $pwd ) = cwd(); # from Cwd.pm
80 14         209 my ( $found ) = 0;
81 14 100       274 if ($Config{gccversion}) {
82 5         178568 chomp(my @incpath = grep s/^ //, grep { /^#include &1 >/dev/null`);
  125         520  
83 5         51 unshift @libpath, map { s{/include[^/]*}{/lib}; $_ } @incpath
  20         139  
  20         83  
84             }
85 14         746 @libpath = grep -d, @libpath;
86              
87 14 50       314 if ($^O eq 'darwin') {
88             # 'escape' Mach-O ld -framework and -F flags, so they aren't dropped later on
89 0 0       0 $found++ if $potential_libs =~ s/(^|\s)(-(?:weak_|reexport_|lazy_)?framework)\s+(\S+)/$1-Wl,$2 -Wl,$3/g;
90 0 0       0 $found++ if $potential_libs =~ s/(^|\s)(-F)\s*(\S+)/$1-Wl,$2 -Wl,$3/g;
91             }
92              
93 14         1399 foreach my $thislib ( Text::ParseWords::shellwords($potential_libs) ) {
94 22         4200 my ( $custom_name ) = '';
95              
96             # Handle possible linker path arguments.
97 22 100       439 if ( $thislib =~ s/^(-[LR]|-Wl,-R|-Wl,-rpath,)// ) { # save path flag type
98 6         84 my ( $ptype ) = $1;
99 6 50       211 unless ( -d $thislib ) {
100 0 0       0 warn "$ptype$thislib ignored, directory does not exist\n"
101             if $verbose;
102 0         0 next;
103             }
104 6         64 my ( $rtype ) = $ptype;
105 6 50 33     127 if ( ( $ptype eq '-R' ) or ( $ptype =~ m!^-Wl,-[Rr]! ) ) {
106 0 0       0 if ( $Config{'lddlflags'} =~ /-Wl,-[Rr]/ ) {
    0          
107 0         0 $rtype = '-Wl,-R';
108             }
109             elsif ( $Config{'lddlflags'} =~ /-R/ ) {
110 0         0 $rtype = '-R';
111             }
112             }
113 6 50       344 unless ( File::Spec->file_name_is_absolute( $thislib ) ) {
114 6         238 warn "Warning: $ptype$thislib changed to $ptype$pwd/$thislib\n";
115 6         219 $thislib = $self->catdir( $pwd, $thislib );
116             }
117 6         83 push( @searchpath, $thislib );
118 6 100       56 $thislib = qq{"$thislib"} if $thislib =~ / /; # protect spaces if there
119 6         80 push( @extralibs, "$ptype$thislib" );
120 6         41 push( @ldloadlibs, "$rtype$thislib" );
121 6         29 next;
122             }
123              
124 16 50       119 if ( $thislib =~ m!^-Wl,! ) {
125 0         0 push( @extralibs, $thislib );
126 0         0 push( @ldloadlibs, $thislib );
127 0         0 next;
128             }
129              
130             # Handle possible library arguments.
131 16 100       238 if ( $thislib =~ s/^-l(:)?// ) {
132             # Handle -l:foo.so, which means that the library will
133             # actually be called foo.so, not libfoo.so. This
134             # is used in Android by ExtUtils::Depends to allow one XS
135             # module to link to another.
136 14   50     208 $custom_name = $1 || '';
137             }
138             else {
139 2         102 warn "Unrecognized argument in LIBS ignored: '$thislib'\n";
140 2         43 next;
141             }
142              
143 14         63 my ( $found_lib ) = 0;
144 14         55 foreach my $thispth ( @searchpath, @libpath ) {
145              
146             # Try to find the full name of the library. We need this to
147             # determine whether it's a dynamically-loadable library or not.
148             # This tends to be subject to various os-specific quirks.
149             # For gcc-2.6.2 on linux (March 1995), DLD can not load
150             # .sa libraries, with the exception of libm.sa, so we
151             # deliberately skip them.
152 56 50 33     4604 if ((@fullname =
    100 33        
    50 33        
    50 66        
    50 33        
    50 33        
    50 0        
    50 33        
    50 33        
    50 33        
    50 33        
    50          
153             $self->lsdir($thispth, "^\Qlib$thislib.$so.\E[0-9]+")) ||
154             (@fullname =
155             $self->lsdir($thispth, "^\Qlib$thislib.\E[0-9]+\Q\.$so"))) {
156             # Take care that libfoo.so.10 wins against libfoo.so.9.
157             # Compare two libraries to find the most recent version
158             # number. E.g. if you have libfoo.so.9.0.7 and
159             # libfoo.so.10.1, first convert all digits into two
160             # decimal places. Then we'll add ".00" to the shorter
161             # strings so that we're comparing strings of equal length
162             # Thus we'll compare libfoo.so.09.07.00 with
163             # libfoo.so.10.01.00. Some libraries might have letters
164             # in the version. We don't know what they mean, but will
165             # try to skip them gracefully -- we'll set any letter to
166             # '0'. Finally, sort in reverse so we can take the
167             # first element.
168              
169             #TODO: iterate through the directory instead of sorting
170              
171             $fullname = "$thispth/" . (
172             sort {
173 0         0 my ( $ma ) = $a;
  0         0  
174 0         0 my ( $mb ) = $b;
175 0         0 $ma =~ tr/A-Za-z/0/s;
176 0         0 $ma =~ s/\b(\d)\b/0$1/g;
177 0         0 $mb =~ tr/A-Za-z/0/s;
178 0         0 $mb =~ s/\b(\d)\b/0$1/g;
179 0         0 while ( length( $ma ) < length( $mb ) ) { $ma .= ".00"; }
  0         0  
180 0         0 while ( length( $mb ) < length( $ma ) ) { $mb .= ".00"; }
  0         0  
181              
182             # Comparison deliberately backwards
183 0         0 $mb cmp $ma;
184             } @fullname
185             )[0];
186             }
187             elsif ( -f ( $fullname = "$thispth/lib$thislib.$so" ) )
188             {
189             }
190             elsif (-f ( $fullname = "$thispth/lib${thislib}_s$Config_libext" )
191             && ( $Config{'archname'} !~ /RM\d\d\d-svr4/ )
192             && ( $thislib .= "_s" ) )
193             { # we must explicitly use _s version
194             }
195             elsif ( -f ( $fullname = "$thispth/lib$thislib$Config_libext" ) ) {
196             }
197             elsif ( defined( $Config_dlext )
198             && -f ( $fullname = "$thispth/lib$thislib.$Config_dlext" ) )
199             {
200             }
201             elsif ( $^O eq 'darwin' && require DynaLoader && defined &DynaLoader::dl_load_file
202             && DynaLoader::dl_load_file( $fullname = "$thispth/lib$thislib.$so", 0 ) )
203             {
204             }
205             elsif ( -f ( $fullname = "$thispth/$thislib$Config_libext" ) ) {
206             }
207             elsif ( -f ( $fullname = "$thispth/lib$thislib.dll$Config_libext" ) ) {
208             }
209             elsif ( $^O eq 'cygwin' && -f ( $fullname = "$thispth/$thislib.dll" ) ) {
210             }
211             elsif ( -f ( $fullname = "$thispth/Slib$thislib$Config_libext" ) ) {
212             }
213             elsif ($^O eq 'dgux'
214             && -l ( $fullname = "$thispth/lib$thislib$Config_libext" )
215             && readlink( $fullname ) =~ /^elink:/s )
216             {
217              
218             # Some of DG's libraries look like misconnected symbolic
219             # links, but development tools can follow them. (They
220             # look like this:
221             #
222             # libm.a -> elink:${SDE_PATH:-/usr}/sde/\
223             # ${TARGET_BINARY_INTERFACE:-m88kdgux}/usr/lib/libm.a
224             #
225             # , the compilation tools expand the environment variables.)
226             }
227             elsif ( $custom_name && -f ( $fullname = "$thispth/$thislib" ) ) {
228             }
229             else {
230 51 50       958 warn "$thislib not found in $thispth\n" if $verbose;
231 51         235 next;
232             }
233 5 50       1445 warn "'-l$thislib' found at $fullname\n" if $verbose;
234 5 50       93 push @libs, $fullname unless $libs_seen{$fullname}++;
235 5         17 $found++;
236 5         11 $found_lib++;
237              
238             # Now update library lists
239              
240             # what do we know about this library...
241             # "Sounds like we should always assume it's a dynamic library on AIX."
242 5 50       87 my $is_dyna = $^O eq 'aix' ? 1 : ( $fullname !~ /\Q$Config_libext\E\z/ );
243 5         136 my $in_perl = ( $libs =~ /\B-l:?\Q${thislib}\E\b/s );
244              
245             # include the path to the lib once in the dynamic linker path
246             # but only if it is a dynamic lib and not in Perl itself
247 5         529 my ( $fullnamedir ) = dirname( $fullname );
248             push @ld_run_path, $fullnamedir
249             if $is_dyna
250             && !$in_perl
251 5 50 33     118 && !$ld_run_path_seen{$fullnamedir}++;
      33        
252              
253             # Do not add it into the list if it is already linked in
254             # with the main perl executable.
255 5 50       33 push( @extralibs, "-l$custom_name$thislib" )
256             unless $in_perl;
257              
258 5 50       20 if ( $is_dyna ) {
259              
260             # For SunOS4, do not add in this shared library if
261             # it is already linked in the main perl executable
262 5 50 33     36 push( @ldloadlibs, "-l$custom_name$thislib" )
263             unless ( $in_perl and $^O eq 'sunos' );
264             }
265             else {
266 0         0 push( @ldloadlibs, "-l$custom_name$thislib" );
267             }
268 5         20 last; # found one here so don't bother looking further
269             }
270 14 100       414 warn "Warning (mostly harmless): " . "No library found for -l$thislib\n"
271             unless $found_lib > 0;
272             }
273              
274 14 100       839 return ( '', '', '', '', ( $give_libs ? \@libs : () ) ) unless $found;
    100          
275 5 50       210 ( "@extralibs", "@bsloadlibs", "@ldloadlibs", join( ":", @ld_run_path ), ( $give_libs ? \@libs : () ) );
276             }
277              
278             sub _win32_ext {
279              
280 0     0     require Text::ParseWords;
281              
282 0           my ( $self, $potential_libs, $verbose, $give_libs ) = @_;
283 0   0       $verbose ||= 0;
284              
285             # If user did not supply a list, we punt.
286             # (caller should probably use the list in $Config{libs})
287 0 0         return ( "", "", "", "", ( $give_libs ? [] : () ) ) unless $potential_libs;
    0          
288              
289             # TODO: make this use MM_Win32.pm's compiler detection
290 0           my %libs_seen;
291             my @extralibs;
292 0   0       my $cc = $Config{cc} || '';
293 0           my $VC = $cc =~ /\bcl\b/i;
294 0           my $GC = $cc =~ /\bgcc\b/i;
295              
296 0           my $libext = _win32_lib_extensions();
297 0           my @searchpath = ( '' ); # from "-L/path" entries in $potential_libs
298 0           my @libpath = _win32_default_search_paths( $VC, $GC );
299 0           my $pwd = cwd(); # from Cwd.pm
300 0           my $search = 1;
301              
302             # compute @extralibs from $potential_libs
303 0           my @lib_search_list = _win32_make_lib_search_list( $potential_libs, $verbose );
304 0           for ( @lib_search_list ) {
305              
306 0           my $thislib = $_;
307              
308             # see if entry is a flag
309 0 0         if ( /^:\w+$/ ) {
310 0 0         $search = 0 if lc eq ':nosearch';
311 0 0         $search = 1 if lc eq ':search';
312 0 0         _debug( "Ignoring unknown flag '$thislib'\n", $verbose ) if !/^:(no)?(search|default)$/i;
313 0           next;
314             }
315              
316             # if searching is disabled, do compiler-specific translations
317 0 0         unless ( $search ) {
318 0 0         s/^-l(.+)$/$1.lib/ unless $GC;
319 0 0         s/^-L/-libpath:/ if $VC;
320 0           push( @extralibs, $_ );
321 0           next;
322             }
323              
324             # handle possible linker path arguments
325 0 0 0       if ( s/^-L// and not -d ) {
    0          
326 0           _debug( "$thislib ignored, directory does not exist\n", $verbose );
327 0           next;
328             }
329             elsif ( -d ) {
330 0 0         unless ( File::Spec->file_name_is_absolute( $_ ) ) {
331 0           warn "Warning: '$thislib' changed to '-L$pwd/$_'\n";
332 0           $_ = $self->catdir( $pwd, $_ );
333             }
334 0           push( @searchpath, $_ );
335 0           next;
336             }
337              
338 0           my @paths = ( @searchpath, @libpath );
339 0           my ( $fullname, $path ) = _win32_search_file( $thislib, $libext, \@paths, $verbose, $GC );
340              
341 0 0         if ( !$fullname ) {
342 0           warn "Warning (mostly harmless): No library found for $thislib\n";
343 0           next;
344             }
345              
346 0           _debug( "'$thislib' found as '$fullname'\n", $verbose );
347 0           push( @extralibs, $fullname );
348 0 0         $libs_seen{$fullname} = 1 if $path; # why is this a special case?
349             }
350              
351 0           my @libs = sort keys %libs_seen;
352              
353 0 0         return ( '', '', '', '', ( $give_libs ? \@libs : () ) ) unless @extralibs;
    0          
354              
355             # make sure paths with spaces are properly quoted
356 0           @extralibs = map { qq["$_"] } @extralibs;
  0            
357 0           @libs = map { qq["$_"] } @libs;
  0            
358              
359 0           my $lib = join( ' ', @extralibs );
360              
361             # normalize back to backward slashes (to help braindead tools)
362             # XXX this may break equally braindead GNU tools that don't understand
363             # backslashes, either. Seems like one can't win here. Cursed be CP/M.
364 0           $lib =~ s,/,\\,g;
365              
366 0           _debug( "Result: $lib\n", $verbose );
367 0 0         wantarray ? ( $lib, '', $lib, '', ( $give_libs ? \@libs : () ) ) : $lib;
    0          
368             }
369              
370             sub _win32_make_lib_search_list {
371 0     0     my ( $potential_libs, $verbose ) = @_;
372 0           _debug( "Potential libraries are '$potential_libs':\n", $verbose );
373 0           $potential_libs =~ s,\\,/,g; # normalize to forward slashes
374 0           Text::ParseWords::quotewords( '\s+', 0, $potential_libs );
375             }
376              
377             sub _win32_default_search_paths {
378 0     0     my ( $VC, $GC ) = @_;
379              
380 0   0       my $libpth = $Config{'libpth'} || '';
381 0           $libpth =~ s,\\,/,g; # normalize to forward slashes
382              
383 0           my @libpath = _space_dirs_split($libpth);
384 0           push @libpath, "$Config{installarchlib}/CORE"; # add "$Config{installarchlib}/CORE" to default search path
385              
386 0 0 0       push @libpath, split /;/, $ENV{LIB} if $VC and $ENV{LIB};
387 0 0 0       push @libpath, split /;/, $ENV{LIBRARY_PATH} if $GC and $ENV{LIBRARY_PATH};
388 0 0         push @libpath, "$ENV{SYSTEMROOT}\\system32" if $ENV{SYSTEMROOT};
389              
390 0           return @libpath;
391             }
392              
393             sub _win32_search_file {
394 0     0     my ( $thislib, $libext, $paths, $verbose, $GC ) = @_;
395              
396 0           my @file_list = _win32_build_file_list( $thislib, $GC, $libext );
397              
398 0           for my $lib_file ( @file_list ) {
399 0           for my $path ( @{$paths} ) {
  0            
400 0           my $fullname = $lib_file;
401 0 0         $fullname = "$path\\$fullname" if $path;
402              
403 0 0         return ( $fullname, $path ) if -f $fullname;
404              
405 0           _debug( "'$thislib' not found as '$fullname'\n", $verbose );
406             }
407             }
408              
409 0           return;
410             }
411              
412             sub _win32_build_file_list {
413 0     0     my ( $lib, $GC, $extensions ) = @_;
414              
415 0           my @pre_fixed = _win32_build_prefixed_list( $lib, $GC );
416 0           return map _win32_attach_extensions( $_, $extensions ), @pre_fixed;
417             }
418              
419             sub _win32_build_prefixed_list {
420 0     0     my ( $lib, $GC ) = @_;
421              
422 0 0         return $lib if $lib !~ s/^-l//;
423 0 0 0       return $lib if $lib =~ /^lib/ and !$GC;
424              
425 0           ( my $no_prefix = $lib ) =~ s/^lib//i;
426 0 0         $lib = "lib$lib" if $no_prefix eq $lib;
427              
428 0 0         return ( $lib, $no_prefix ) if $GC;
429 0           return ( $no_prefix, $lib );
430             }
431              
432             sub _win32_attach_extensions {
433 0     0     my ( $lib, $extensions ) = @_;
434 0           return map _win32_try_attach_extension( $lib, $_ ), @{$extensions};
  0            
435             }
436              
437             sub _win32_try_attach_extension {
438 0     0     my ( $lib, $extension ) = @_;
439              
440 0 0         return $lib if $lib =~ /\Q$extension\E$/i;
441 0           return "$lib$extension";
442             }
443              
444             sub _win32_lib_extensions {
445 0     0     my @extensions = grep $_, @Config{qw(lib_ext)};
446 0           push @extensions, map ".$_", grep $_, @Config{qw(dlext so)};
447 0 0         push @extensions, '.dll.a' if grep { m!^\.a$! } @extensions;
  0            
448 0 0         push @extensions, '.lib' unless grep { m!^\.lib$! } @extensions;
  0            
449 0           return \@extensions;
450             }
451              
452             sub _debug {
453 0     0     my ( $message, $verbose ) = @_;
454 0 0         return if !$verbose;
455 0           warn $message;
456 0           return;
457             }
458              
459             sub _vms_ext {
460 0     0     my ( $self, $potential_libs, $verbose, $give_libs ) = @_;
461 0   0       $verbose ||= 0;
462              
463 0           my ( @crtls, $crtlstr );
464 0 0         @crtls = ( ( $Config{'ldflags'} =~ m-/Debug-i ? $Config{'dbgprefix'} : '' ) . 'PerlShr/Share' );
465 0           push( @crtls, grep { not /\(/ } split /\s+/, $Config{'perllibs'} );
  0            
466 0           push( @crtls, grep { not /\(/ } split /\s+/, $Config{'libc'} );
  0            
467              
468             # In general, we pass through the basic libraries from %Config unchanged.
469             # The one exception is that if we're building in the Perl source tree, and
470             # a library spec could be resolved via a logical name, we go to some trouble
471             # to insure that the copy in the local tree is used, rather than one to
472             # which a system-wide logical may point.
473 0 0         if ( $self->{PERL_SRC} ) {
474 0           my ( $locspec, $type );
475 0           foreach my $lib ( @crtls ) {
476 0 0 0       if ( ( $locspec, $type ) = $lib =~ m{^([\w\$-]+)(/\w+)?} and $locspec =~ /perl/i ) {
477 0 0         if ( lc $type eq '/share' ) { $locspec .= $Config{'exe_ext'}; }
  0 0          
478 0           elsif ( lc $type eq '/library' ) { $locspec .= $Config{'lib_ext'}; }
479 0           else { $locspec .= $Config{'obj_ext'}; }
480 0           $locspec = $self->catfile( $self->{PERL_SRC}, $locspec );
481 0 0         $lib = "$locspec$type" if -e $locspec;
482             }
483             }
484             }
485 0 0         $crtlstr = @crtls ? join( ' ', @crtls ) : '';
486              
487 0 0         unless ( $potential_libs ) {
488 0 0         warn "Result:\n\tEXTRALIBS: \n\tLDLOADLIBS: $crtlstr\n" if $verbose;
489 0 0         return ( '', '', $crtlstr, '', ( $give_libs ? [] : () ) );
490             }
491              
492 0           my ( %found, @fndlibs, $ldlib );
493 0           my $cwd = cwd();
494 0           my ( $so, $lib_ext, $obj_ext ) = @Config{ 'so', 'lib_ext', 'obj_ext' };
495              
496             # List of common Unix library names and their VMS equivalents
497             # (VMS equivalent of '' indicates that the library is automatically
498             # searched by the linker, and should be skipped here.)
499 0           my ( @flibs, %libs_seen );
500 0           my %libmap = (
501             'm' => '',
502             'f77' => '',
503             'F77' => '',
504             'V77' => '',
505             'c' => '',
506             'malloc' => '',
507             'crypt' => '',
508             'resolv' => '',
509             'c_s' => '',
510             'socket' => '',
511             'X11' => 'DECW$XLIBSHR',
512             'Xt' => 'DECW$XTSHR',
513             'Xm' => 'DECW$XMLIBSHR',
514             'Xmu' => 'DECW$XMULIBSHR'
515             );
516              
517 0 0         warn "Potential libraries are '$potential_libs'\n" if $verbose;
518              
519             # First, sort out directories and library names in the input
520 0           my ( @dirs, @libs );
521 0           foreach my $lib ( split ' ', $potential_libs ) {
522 0 0         push( @dirs, $1 ), next if $lib =~ /^-L(.*)/;
523 0 0         push( @dirs, $lib ), next if $lib =~ /[:>\]]$/;
524 0 0         push( @dirs, $lib ), next if -d $lib;
525 0 0         push( @libs, $1 ), next if $lib =~ /^-l(.*)/;
526 0           push( @libs, $lib );
527             }
528 0           push( @dirs, split( ' ', $Config{'libpth'} ) );
529              
530             # Now make sure we've got VMS-syntax absolute directory specs
531             # (We don't, however, check whether someone's hidden a relative
532             # path in a logical name.)
533 0           foreach my $dir ( @dirs ) {
534 0 0         unless ( -d $dir ) {
535 0 0         warn "Skipping nonexistent Directory $dir\n" if $verbose > 1;
536 0           $dir = '';
537 0           next;
538             }
539 0 0         warn "Resolving directory $dir\n" if $verbose;
540 0 0         if ( File::Spec->file_name_is_absolute( $dir ) ) {
541 0           $dir = VMS::Filespec::vmspath( $dir );
542             }
543             else {
544 0           $dir = $self->catdir( $cwd, $dir );
545             }
546             }
547 0           @dirs = grep { length( $_ ) } @dirs;
  0            
548 0           unshift( @dirs, '' ); # Check each $lib without additions first
549              
550 0           LIB: foreach my $lib ( @libs ) {
551 0 0         if ( exists $libmap{$lib} ) {
552 0 0         next unless length $libmap{$lib};
553 0           $lib = $libmap{$lib};
554             }
555              
556 0           my ( @variants, $cand );
557 0           my ( $ctype ) = '';
558              
559             # If we don't have a file type, consider it a possibly abbreviated name and
560             # check for common variants. We try these first to grab libraries before
561             # a like-named executable image (e.g. -lperl resolves to perlshr.exe
562             # before perl.exe).
563 0 0         if ( $lib !~ /\.[^:>\]]*$/ ) {
564 0           push( @variants, "${lib}shr", "${lib}rtl", "${lib}lib" );
565 0 0         push( @variants, "lib$lib" ) if $lib !~ /[:>\]]/;
566             }
567 0           push( @variants, $lib );
568 0 0         warn "Looking for $lib\n" if $verbose;
569 0           foreach my $variant ( @variants ) {
570 0           my ( $fullname, $name );
571              
572 0           foreach my $dir ( @dirs ) {
573 0           my ( $type );
574              
575 0           $name = "$dir$variant";
576 0 0         warn "\tChecking $name\n" if $verbose > 2;
577 0           $fullname = VMS::Filespec::rmsexpand( $name );
578 0 0 0       if ( defined $fullname and -f $fullname ) {
    0 0        
    0 0        
    0 0        
      0        
      0        
579              
580             # It's got its own suffix, so we'll have to figure out the type
581 0 0         if ( $fullname =~ /(?:$so|exe)$/i ) { $type = 'SHR'; }
  0 0          
    0          
582 0           elsif ( $fullname =~ /(?:$lib_ext|olb)$/i ) { $type = 'OLB'; }
583             elsif ( $fullname =~ /(?:$obj_ext|obj)$/i ) {
584 0           warn "Warning (mostly harmless): " . "Plain object file $fullname found in library list\n";
585 0           $type = 'OBJ';
586             }
587             else {
588 0           warn "Warning (mostly harmless): " . "Unknown library type for $fullname; assuming shared\n";
589 0           $type = 'SHR';
590             }
591             }
592             elsif (-f ( $fullname = VMS::Filespec::rmsexpand( $name, $so ) )
593             or -f ( $fullname = VMS::Filespec::rmsexpand( $name, '.exe' ) ) )
594             {
595 0           $type = 'SHR';
596 0 0         $name = $fullname unless $fullname =~ /exe;?\d*$/i;
597             }
598             elsif (
599             not length( $ctype ) and # If we've got a lib already,
600             # don't bother
601             ( -f ( $fullname = VMS::Filespec::rmsexpand( $name, $lib_ext ) ) or -f ( $fullname = VMS::Filespec::rmsexpand( $name, '.olb' ) ) )
602             )
603             {
604 0           $type = 'OLB';
605 0 0         $name = $fullname unless $fullname =~ /olb;?\d*$/i;
606             }
607             elsif (
608             not length( $ctype ) and # If we've got a lib already,
609             # don't bother
610             ( -f ( $fullname = VMS::Filespec::rmsexpand( $name, $obj_ext ) ) or -f ( $fullname = VMS::Filespec::rmsexpand( $name, '.obj' ) ) )
611             )
612             {
613 0           warn "Warning (mostly harmless): " . "Plain object file $fullname found in library list\n";
614 0           $type = 'OBJ';
615 0 0         $name = $fullname unless $fullname =~ /obj;?\d*$/i;
616             }
617 0 0         if ( defined $type ) {
618 0           $ctype = $type;
619 0           $cand = $name;
620 0 0         last if $ctype eq 'SHR';
621             }
622             }
623 0 0         if ( $ctype ) {
624              
625 0           push @{ $found{$ctype} }, $cand;
  0            
626 0 0         warn "\tFound as $cand (really $fullname), type $ctype\n"
627             if $verbose > 1;
628 0 0         push @flibs, $name unless $libs_seen{$fullname}++;
629 0           next LIB;
630             }
631             }
632 0           warn "Warning (mostly harmless): " . "No library found for $lib\n";
633             }
634              
635 0 0         push @fndlibs, @{ $found{OBJ} } if exists $found{OBJ};
  0            
636 0 0         push @fndlibs, map { "$_/Library" } @{ $found{OLB} } if exists $found{OLB};
  0            
  0            
637 0 0         push @fndlibs, map { "$_/Share" } @{ $found{SHR} } if exists $found{SHR};
  0            
  0            
638 0           my $lib = join( ' ', @fndlibs );
639              
640 0 0         $ldlib = $crtlstr ? "$lib $crtlstr" : $lib;
641 0           $ldlib =~ s/^\s+|\s+$//g;
642 0 0         warn "Result:\n\tEXTRALIBS: $lib\n\tLDLOADLIBS: $ldlib\n" if $verbose;
643 0 0         wantarray ? ( $lib, '', $ldlib, '', ( $give_libs ? \@flibs : () ) ) : $lib;
    0          
644             }
645              
646             1;