File Coverage

lib/ExtUtils/Liblist/Kid.pm
Criterion Covered Total %
statement 90 327 27.5
branch 50 248 20.1
condition 30 124 24.1
subroutine 9 20 45.0
pod 0 1 0.0
total 179 720 24.8


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